oleaut32/tests: Test more return values.
[wine.git] / dlls / taskschd / task.c
bloba8b819c360c2fc7d2be072d137a07d1e7231c6ec
1 /*
2 * Copyright 2013 Dmitry Timoshkov
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 "initguid.h"
26 #include "objbase.h"
27 #include "xmllite.h"
28 #include "taskschd.h"
29 #include "winsvc.h"
30 #include "schrpc.h"
31 #include "taskschd_private.h"
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(taskschd);
38 typedef struct {
39 IDailyTrigger IDailyTrigger_iface;
40 LONG ref;
41 short interval;
42 WCHAR *start_boundary;
43 BOOL enabled;
44 } DailyTrigger;
46 static inline DailyTrigger *impl_from_IDailyTrigger(IDailyTrigger *iface)
48 return CONTAINING_RECORD(iface, DailyTrigger, IDailyTrigger_iface);
51 static HRESULT WINAPI DailyTrigger_QueryInterface(IDailyTrigger *iface, REFIID riid, void **ppv)
53 DailyTrigger *This = impl_from_IDailyTrigger(iface);
55 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
57 if(IsEqualGUID(&IID_IUnknown, riid) ||
58 IsEqualGUID(&IID_IDispatch, riid) ||
59 IsEqualGUID(&IID_ITrigger, riid) ||
60 IsEqualGUID(&IID_IDailyTrigger, riid))
62 *ppv = &This->IDailyTrigger_iface;
64 else
66 FIXME("unsupported riid %s\n", debugstr_guid(riid));
67 *ppv = NULL;
68 return E_NOINTERFACE;
71 IUnknown_AddRef((IUnknown*)*ppv);
72 return S_OK;
75 static ULONG WINAPI DailyTrigger_AddRef(IDailyTrigger *iface)
77 DailyTrigger *This = impl_from_IDailyTrigger(iface);
78 LONG ref = InterlockedIncrement(&This->ref);
80 TRACE("(%p) ref=%d\n", This, ref);
82 return ref;
85 static ULONG WINAPI DailyTrigger_Release(IDailyTrigger *iface)
87 DailyTrigger *This = impl_from_IDailyTrigger(iface);
88 LONG ref = InterlockedDecrement(&This->ref);
90 TRACE("(%p) ref=%d\n", This, ref);
92 if(!ref)
94 TRACE("destroying %p\n", iface);
95 heap_free(This->start_boundary);
96 heap_free(This);
99 return ref;
102 static HRESULT WINAPI DailyTrigger_GetTypeInfoCount(IDailyTrigger *iface, UINT *count)
104 DailyTrigger *This = impl_from_IDailyTrigger(iface);
105 FIXME("(%p)->(%p)\n", This, count);
106 return E_NOTIMPL;
109 static HRESULT WINAPI DailyTrigger_GetTypeInfo(IDailyTrigger *iface, UINT index, LCID lcid, ITypeInfo **info)
111 DailyTrigger *This = impl_from_IDailyTrigger(iface);
112 FIXME("(%p)->(%u %u %p)\n", This, index, lcid, info);
113 return E_NOTIMPL;
116 static HRESULT WINAPI DailyTrigger_GetIDsOfNames(IDailyTrigger *iface, REFIID riid, LPOLESTR *names,
117 UINT count, LCID lcid, DISPID *dispid)
119 DailyTrigger *This = impl_from_IDailyTrigger(iface);
120 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), names, count, lcid, dispid);
121 return E_NOTIMPL;
124 static HRESULT WINAPI DailyTrigger_Invoke(IDailyTrigger *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
125 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
127 DailyTrigger *This = impl_from_IDailyTrigger(iface);
128 FIXME("(%p)->(%d %s %x %x %p %p %p %p)\n", This, dispid, debugstr_guid(riid), lcid, flags,
129 params, result, excepinfo, argerr);
130 return E_NOTIMPL;
133 static HRESULT WINAPI DailyTrigger_get_Type(IDailyTrigger *iface, TASK_TRIGGER_TYPE2 *type)
135 DailyTrigger *This = impl_from_IDailyTrigger(iface);
136 FIXME("(%p)->(%p)\n", This, type);
137 return E_NOTIMPL;
140 static HRESULT WINAPI DailyTrigger_get_Id(IDailyTrigger *iface, BSTR *id)
142 DailyTrigger *This = impl_from_IDailyTrigger(iface);
143 FIXME("(%p)->(%p)\n", This, id);
144 return E_NOTIMPL;
147 static HRESULT WINAPI DailyTrigger_put_Id(IDailyTrigger *iface, BSTR id)
149 DailyTrigger *This = impl_from_IDailyTrigger(iface);
150 FIXME("(%p)->(%s)\n", This, debugstr_w(id));
151 return E_NOTIMPL;
154 static HRESULT WINAPI DailyTrigger_get_Repetition(IDailyTrigger *iface, IRepetitionPattern **repeat)
156 DailyTrigger *This = impl_from_IDailyTrigger(iface);
157 FIXME("(%p)->(%p)\n", This, repeat);
158 return E_NOTIMPL;
161 static HRESULT WINAPI DailyTrigger_put_Repetition(IDailyTrigger *iface, IRepetitionPattern *repeat)
163 DailyTrigger *This = impl_from_IDailyTrigger(iface);
164 FIXME("(%p)->(%p)\n", This, repeat);
165 return E_NOTIMPL;
168 static HRESULT WINAPI DailyTrigger_get_ExecutionTimeLimit(IDailyTrigger *iface, BSTR *limit)
170 DailyTrigger *This = impl_from_IDailyTrigger(iface);
171 FIXME("(%p)->(%p)\n", This, limit);
172 return E_NOTIMPL;
175 static HRESULT WINAPI DailyTrigger_put_ExecutionTimeLimit(IDailyTrigger *iface, BSTR limit)
177 DailyTrigger *This = impl_from_IDailyTrigger(iface);
178 FIXME("(%p)->(%s)\n", This, debugstr_w(limit));
179 return E_NOTIMPL;
182 static HRESULT WINAPI DailyTrigger_get_StartBoundary(IDailyTrigger *iface, BSTR *start)
184 DailyTrigger *This = impl_from_IDailyTrigger(iface);
186 TRACE("(%p)->(%p)\n", This, start);
188 if (!start) return E_POINTER;
190 if (!This->start_boundary) *start = NULL;
191 else if (!(*start = SysAllocString(This->start_boundary))) return E_OUTOFMEMORY;
193 return S_OK;
196 static HRESULT WINAPI DailyTrigger_put_StartBoundary(IDailyTrigger *iface, BSTR start)
198 DailyTrigger *This = impl_from_IDailyTrigger(iface);
199 WCHAR *str = NULL;
201 TRACE("(%p)->(%s)\n", This, debugstr_w(start));
203 if (start && !(str = heap_strdupW(start))) return E_OUTOFMEMORY;
204 heap_free(This->start_boundary);
205 This->start_boundary = str;
207 return S_OK;
210 static HRESULT WINAPI DailyTrigger_get_EndBoundary(IDailyTrigger *iface, BSTR *end)
212 DailyTrigger *This = impl_from_IDailyTrigger(iface);
213 FIXME("(%p)->(%p)\n", This, end);
214 return E_NOTIMPL;
217 static HRESULT WINAPI DailyTrigger_put_EndBoundary(IDailyTrigger *iface, BSTR end)
219 DailyTrigger *This = impl_from_IDailyTrigger(iface);
220 FIXME("(%p)->(%s)\n", This, debugstr_w(end));
221 return E_NOTIMPL;
224 static HRESULT WINAPI DailyTrigger_get_Enabled(IDailyTrigger *iface, VARIANT_BOOL *enabled)
226 DailyTrigger *This = impl_from_IDailyTrigger(iface);
228 TRACE("(%p)->(%p)\n", This, enabled);
230 if (!enabled) return E_POINTER;
232 *enabled = This->enabled ? VARIANT_TRUE : VARIANT_FALSE;
233 return S_OK;
236 static HRESULT WINAPI DailyTrigger_put_Enabled(IDailyTrigger *iface, VARIANT_BOOL enabled)
238 DailyTrigger *This = impl_from_IDailyTrigger(iface);
240 TRACE("(%p)->(%x)\n", This, enabled);
242 This->enabled = enabled ? TRUE : FALSE;
243 return S_OK;
246 static HRESULT WINAPI DailyTrigger_get_DaysInterval(IDailyTrigger *iface, short *days)
248 DailyTrigger *This = impl_from_IDailyTrigger(iface);
250 TRACE("(%p)->(%p)\n", This, days);
252 *days = This->interval;
253 return S_OK;
256 static HRESULT WINAPI DailyTrigger_put_DaysInterval(IDailyTrigger *iface, short days)
258 DailyTrigger *This = impl_from_IDailyTrigger(iface);
260 TRACE("(%p)->(%d)\n", This, days);
262 if(days <= 0)
263 return E_INVALIDARG;
265 This->interval = days;
266 return S_OK;
269 static HRESULT WINAPI DailyTrigger_get_RandomDelay(IDailyTrigger *iface, BSTR *pRandomDelay)
271 DailyTrigger *This = impl_from_IDailyTrigger(iface);
272 FIXME("(%p)->(%p)\n", This, pRandomDelay);
273 return E_NOTIMPL;
276 static HRESULT WINAPI DailyTrigger_put_RandomDelay(IDailyTrigger *iface, BSTR randomDelay)
278 DailyTrigger *This = impl_from_IDailyTrigger(iface);
279 FIXME("(%p)->(%s)\n", This, debugstr_w(randomDelay));
280 return E_NOTIMPL;
283 static const IDailyTriggerVtbl DailyTrigger_vtbl = {
284 DailyTrigger_QueryInterface,
285 DailyTrigger_AddRef,
286 DailyTrigger_Release,
287 DailyTrigger_GetTypeInfoCount,
288 DailyTrigger_GetTypeInfo,
289 DailyTrigger_GetIDsOfNames,
290 DailyTrigger_Invoke,
291 DailyTrigger_get_Type,
292 DailyTrigger_get_Id,
293 DailyTrigger_put_Id,
294 DailyTrigger_get_Repetition,
295 DailyTrigger_put_Repetition,
296 DailyTrigger_get_ExecutionTimeLimit,
297 DailyTrigger_put_ExecutionTimeLimit,
298 DailyTrigger_get_StartBoundary,
299 DailyTrigger_put_StartBoundary,
300 DailyTrigger_get_EndBoundary,
301 DailyTrigger_put_EndBoundary,
302 DailyTrigger_get_Enabled,
303 DailyTrigger_put_Enabled,
304 DailyTrigger_get_DaysInterval,
305 DailyTrigger_put_DaysInterval,
306 DailyTrigger_get_RandomDelay,
307 DailyTrigger_put_RandomDelay
310 static HRESULT DailyTrigger_create(ITrigger **trigger)
312 DailyTrigger *daily_trigger;
314 daily_trigger = heap_alloc(sizeof(*daily_trigger));
315 if (!daily_trigger)
316 return E_OUTOFMEMORY;
318 daily_trigger->IDailyTrigger_iface.lpVtbl = &DailyTrigger_vtbl;
319 daily_trigger->ref = 1;
320 daily_trigger->interval = 1;
321 daily_trigger->start_boundary = NULL;
322 daily_trigger->enabled = TRUE;
324 *trigger = (ITrigger*)&daily_trigger->IDailyTrigger_iface;
325 return S_OK;
328 typedef struct
330 ITriggerCollection ITriggerCollection_iface;
331 LONG ref;
332 } trigger_collection;
334 static inline trigger_collection *impl_from_ITriggerCollection(ITriggerCollection *iface)
336 return CONTAINING_RECORD(iface, trigger_collection, ITriggerCollection_iface);
339 static HRESULT WINAPI TriggerCollection_QueryInterface(ITriggerCollection *iface, REFIID riid, void **ppv)
341 trigger_collection *This = impl_from_ITriggerCollection(iface);
343 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
345 if(IsEqualGUID(&IID_IUnknown, riid) ||
346 IsEqualGUID(&IID_IDispatch, riid) ||
347 IsEqualGUID(&IID_ITriggerCollection, riid)) {
348 *ppv = &This->ITriggerCollection_iface;
349 }else {
350 FIXME("unimplemented interface %s\n", debugstr_guid(riid));
351 *ppv = NULL;
352 return E_NOINTERFACE;
355 IUnknown_AddRef((IUnknown*)*ppv);
356 return S_OK;
359 static ULONG WINAPI TriggerCollection_AddRef(ITriggerCollection *iface)
361 trigger_collection *This = impl_from_ITriggerCollection(iface);
362 LONG ref = InterlockedIncrement(&This->ref);
364 TRACE("(%p) ref=%d\n", This, ref);
366 return ref;
369 static ULONG WINAPI TriggerCollection_Release(ITriggerCollection *iface)
371 trigger_collection *This = impl_from_ITriggerCollection(iface);
372 LONG ref = InterlockedDecrement(&This->ref);
374 TRACE("(%p) ref=%d\n", This, ref);
376 if(!ref)
377 heap_free(This);
379 return ref;
382 static HRESULT WINAPI TriggerCollection_GetTypeInfoCount(ITriggerCollection *iface, UINT *count)
384 trigger_collection *This = impl_from_ITriggerCollection(iface);
385 FIXME("(%p)->(%p)\n", This, count);
386 return E_NOTIMPL;
389 static HRESULT WINAPI TriggerCollection_GetTypeInfo(ITriggerCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
391 trigger_collection *This = impl_from_ITriggerCollection(iface);
392 FIXME("(%p)->(%u %u %p)\n", This, index, lcid, info);
393 return E_NOTIMPL;
396 static HRESULT WINAPI TriggerCollection_GetIDsOfNames(ITriggerCollection *iface, REFIID riid, LPOLESTR *names,
397 UINT count, LCID lcid, DISPID *dispid)
399 trigger_collection *This = impl_from_ITriggerCollection(iface);
400 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), names, count, lcid, dispid);
401 return E_NOTIMPL;
404 static HRESULT WINAPI TriggerCollection_Invoke(ITriggerCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
405 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
407 trigger_collection *This = impl_from_ITriggerCollection(iface);
408 FIXME("(%p)->(%d %s %x %x %p %p %p %p)\n", This, dispid, debugstr_guid(riid), lcid, flags,
409 params, result, excepinfo, argerr);
410 return E_NOTIMPL;
413 static HRESULT WINAPI TriggerCollection_get_Count(ITriggerCollection *iface, LONG *count)
415 trigger_collection *This = impl_from_ITriggerCollection(iface);
416 FIXME("(%p)->(%p)\n", This, count);
417 return E_NOTIMPL;
420 static HRESULT WINAPI TriggerCollection_get_Item(ITriggerCollection *iface, LONG index, ITrigger **trigger)
422 trigger_collection *This = impl_from_ITriggerCollection(iface);
423 FIXME("(%p)->(%d %p)\n", This, index, trigger);
424 return E_NOTIMPL;
427 static HRESULT WINAPI TriggerCollection_get__NewEnum(ITriggerCollection *iface, IUnknown **penum)
429 trigger_collection *This = impl_from_ITriggerCollection(iface);
430 FIXME("(%p)->(%p)\n", This, penum);
431 return E_NOTIMPL;
434 static HRESULT WINAPI TriggerCollection_Create(ITriggerCollection *iface, TASK_TRIGGER_TYPE2 type, ITrigger **trigger)
436 trigger_collection *This = impl_from_ITriggerCollection(iface);
438 TRACE("(%p)->(%d %p)\n", This, type, trigger);
440 switch(type) {
441 case TASK_TRIGGER_DAILY:
442 return DailyTrigger_create(trigger);
443 default:
444 FIXME("Unimplemented type %d\n", type);
445 return E_NOTIMPL;
448 return S_OK;
451 static HRESULT WINAPI TriggerCollection_Remove(ITriggerCollection *iface, VARIANT index)
453 trigger_collection *This = impl_from_ITriggerCollection(iface);
454 FIXME("(%p)->(%s)\n", This, debugstr_variant(&index));
455 return E_NOTIMPL;
458 static HRESULT WINAPI TriggerCollection_Clear(ITriggerCollection *iface)
460 trigger_collection *This = impl_from_ITriggerCollection(iface);
461 FIXME("(%p)\n", This);
462 return E_NOTIMPL;
465 static const ITriggerCollectionVtbl TriggerCollection_vtbl = {
466 TriggerCollection_QueryInterface,
467 TriggerCollection_AddRef,
468 TriggerCollection_Release,
469 TriggerCollection_GetTypeInfoCount,
470 TriggerCollection_GetTypeInfo,
471 TriggerCollection_GetIDsOfNames,
472 TriggerCollection_Invoke,
473 TriggerCollection_get_Count,
474 TriggerCollection_get_Item,
475 TriggerCollection_get__NewEnum,
476 TriggerCollection_Create,
477 TriggerCollection_Remove,
478 TriggerCollection_Clear
481 typedef struct
483 IRegistrationInfo IRegistrationInfo_iface;
484 LONG ref;
485 WCHAR *description, *author, *version, *date, *documentation, *uri, *source;
486 } registration_info;
488 static inline registration_info *impl_from_IRegistrationInfo(IRegistrationInfo *iface)
490 return CONTAINING_RECORD(iface, registration_info, IRegistrationInfo_iface);
493 static ULONG WINAPI RegistrationInfo_AddRef(IRegistrationInfo *iface)
495 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
496 return InterlockedIncrement(&reginfo->ref);
499 static ULONG WINAPI RegistrationInfo_Release(IRegistrationInfo *iface)
501 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
502 LONG ref = InterlockedDecrement(&reginfo->ref);
504 if (!ref)
506 TRACE("destroying %p\n", iface);
507 heap_free(reginfo->description);
508 heap_free(reginfo->author);
509 heap_free(reginfo->version);
510 heap_free(reginfo->date);
511 heap_free(reginfo->documentation);
512 heap_free(reginfo->uri);
513 heap_free(reginfo->source);
514 heap_free(reginfo);
517 return ref;
520 static HRESULT WINAPI RegistrationInfo_QueryInterface(IRegistrationInfo *iface, REFIID riid, void **obj)
522 if (!riid || !obj) return E_INVALIDARG;
524 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
526 if (IsEqualGUID(riid, &IID_IRegistrationInfo) ||
527 IsEqualGUID(riid, &IID_IDispatch) ||
528 IsEqualGUID(riid, &IID_IUnknown))
530 IRegistrationInfo_AddRef(iface);
531 *obj = iface;
532 return S_OK;
535 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
536 *obj = NULL;
537 return E_NOINTERFACE;
540 static HRESULT WINAPI RegistrationInfo_GetTypeInfoCount(IRegistrationInfo *iface, UINT *count)
542 FIXME("%p,%p: stub\n", iface, count);
543 return E_NOTIMPL;
546 static HRESULT WINAPI RegistrationInfo_GetTypeInfo(IRegistrationInfo *iface, UINT index, LCID lcid, ITypeInfo **info)
548 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
549 return E_NOTIMPL;
552 static HRESULT WINAPI RegistrationInfo_GetIDsOfNames(IRegistrationInfo *iface, REFIID riid, LPOLESTR *names,
553 UINT count, LCID lcid, DISPID *dispid)
555 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
556 return E_NOTIMPL;
559 static HRESULT WINAPI RegistrationInfo_Invoke(IRegistrationInfo *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
560 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
562 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
563 params, result, excepinfo, argerr);
564 return E_NOTIMPL;
567 static HRESULT WINAPI RegistrationInfo_get_Description(IRegistrationInfo *iface, BSTR *description)
569 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
571 TRACE("%p,%p\n", iface, description);
573 if (!description) return E_POINTER;
575 if (!reginfo->description) *description = NULL;
576 else if (!(*description = SysAllocString(reginfo->description))) return E_OUTOFMEMORY;
578 return S_OK;
581 static HRESULT WINAPI RegistrationInfo_put_Description(IRegistrationInfo *iface, BSTR description)
583 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
585 TRACE("%p,%s\n", iface, debugstr_w(description));
587 if (!description) return E_INVALIDARG;
589 heap_free(reginfo->description);
590 reginfo->description = heap_strdupW(description);
591 /* FIXME: update XML on the server side */
592 return reginfo->description ? S_OK : E_OUTOFMEMORY;
595 static HRESULT WINAPI RegistrationInfo_get_Author(IRegistrationInfo *iface, BSTR *author)
597 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
599 TRACE("%p,%p\n", iface, author);
601 if (!author) return E_POINTER;
603 if (!reginfo->author) *author = NULL;
604 else if (!(*author = SysAllocString(reginfo->author))) return E_OUTOFMEMORY;
606 return S_OK;
609 static HRESULT WINAPI RegistrationInfo_put_Author(IRegistrationInfo *iface, BSTR author)
611 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
613 TRACE("%p,%s\n", iface, debugstr_w(author));
615 if (!author) return E_INVALIDARG;
617 heap_free(reginfo->author);
618 reginfo->author = heap_strdupW(author);
619 /* FIXME: update XML on the server side */
620 return reginfo->author ? S_OK : E_OUTOFMEMORY;
623 static HRESULT WINAPI RegistrationInfo_get_Version(IRegistrationInfo *iface, BSTR *version)
625 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
627 TRACE("%p,%p\n", iface, version);
629 if (!version) return E_POINTER;
631 if (!reginfo->version) *version = NULL;
632 else if (!(*version = SysAllocString(reginfo->version))) return E_OUTOFMEMORY;
634 return S_OK;
637 static HRESULT WINAPI RegistrationInfo_put_Version(IRegistrationInfo *iface, BSTR version)
639 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
641 TRACE("%p,%s\n", iface, debugstr_w(version));
643 if (!version) return E_INVALIDARG;
645 heap_free(reginfo->version);
646 reginfo->version = heap_strdupW(version);
647 /* FIXME: update XML on the server side */
648 return reginfo->version ? S_OK : E_OUTOFMEMORY;
651 static HRESULT WINAPI RegistrationInfo_get_Date(IRegistrationInfo *iface, BSTR *date)
653 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
655 TRACE("%p,%p\n", iface, date);
657 if (!date) return E_POINTER;
659 if (!reginfo->date) *date = NULL;
660 else if (!(*date = SysAllocString(reginfo->date))) return E_OUTOFMEMORY;
662 return S_OK;
665 static HRESULT WINAPI RegistrationInfo_put_Date(IRegistrationInfo *iface, BSTR date)
667 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
669 TRACE("%p,%s\n", iface, debugstr_w(date));
671 if (!date) return E_INVALIDARG;
673 heap_free(reginfo->date);
674 reginfo->date = heap_strdupW(date);
675 /* FIXME: update XML on the server side */
676 return reginfo->date ? S_OK : E_OUTOFMEMORY;
679 static HRESULT WINAPI RegistrationInfo_get_Documentation(IRegistrationInfo *iface, BSTR *doc)
681 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
683 TRACE("%p,%p\n", iface, doc);
685 if (!doc) return E_POINTER;
687 if (!reginfo->documentation) *doc = NULL;
688 else if (!(*doc = SysAllocString(reginfo->documentation))) return E_OUTOFMEMORY;
690 return S_OK;
693 static HRESULT WINAPI RegistrationInfo_put_Documentation(IRegistrationInfo *iface, BSTR doc)
695 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
697 TRACE("%p,%s\n", iface, debugstr_w(doc));
699 if (!doc) return E_INVALIDARG;
701 heap_free(reginfo->documentation);
702 reginfo->documentation = heap_strdupW(doc);
703 /* FIXME: update XML on the server side */
704 return reginfo->documentation ? S_OK : E_OUTOFMEMORY;
707 static HRESULT WINAPI RegistrationInfo_get_XmlText(IRegistrationInfo *iface, BSTR *xml)
709 FIXME("%p,%p: stub\n", iface, xml);
710 return E_NOTIMPL;
713 static HRESULT WINAPI RegistrationInfo_put_XmlText(IRegistrationInfo *iface, BSTR xml)
715 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
716 return E_NOTIMPL;
719 static HRESULT WINAPI RegistrationInfo_get_URI(IRegistrationInfo *iface, BSTR *uri)
721 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
723 TRACE("%p,%p\n", iface, uri);
725 if (!uri) return E_POINTER;
727 if (!reginfo->uri) *uri = NULL;
728 else if (!(*uri = SysAllocString(reginfo->uri))) return E_OUTOFMEMORY;
730 return S_OK;
733 static HRESULT WINAPI RegistrationInfo_put_URI(IRegistrationInfo *iface, BSTR uri)
735 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
737 TRACE("%p,%s\n", iface, debugstr_w(uri));
739 if (!uri) return E_INVALIDARG;
741 heap_free(reginfo->uri);
742 reginfo->uri = heap_strdupW(uri);
743 /* FIXME: update XML on the server side */
744 return reginfo->uri ? S_OK : E_OUTOFMEMORY;
747 static HRESULT WINAPI RegistrationInfo_get_SecurityDescriptor(IRegistrationInfo *iface, VARIANT *sddl)
749 FIXME("%p,%p: stub\n", iface, sddl);
750 return E_NOTIMPL;
753 static HRESULT WINAPI RegistrationInfo_put_SecurityDescriptor(IRegistrationInfo *iface, VARIANT sddl)
755 FIXME("%p,%s: stub\n", iface, debugstr_variant(&sddl));
756 return S_OK;
759 static HRESULT WINAPI RegistrationInfo_get_Source(IRegistrationInfo *iface, BSTR *source)
761 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
763 TRACE("%p,%p\n", iface, source);
765 if (!source) return E_POINTER;
767 if (!reginfo->source) *source = NULL;
768 else if (!(*source = SysAllocString(reginfo->source))) return E_OUTOFMEMORY;
770 return S_OK;
773 static HRESULT WINAPI RegistrationInfo_put_Source(IRegistrationInfo *iface, BSTR source)
775 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
777 TRACE("%p,%s\n", iface, debugstr_w(source));
779 if (!source) return E_INVALIDARG;
781 heap_free(reginfo->source);
782 reginfo->source = heap_strdupW(source);
783 /* FIXME: update XML on the server side */
784 return reginfo->source ? S_OK : E_OUTOFMEMORY;
787 static const IRegistrationInfoVtbl RegistrationInfo_vtbl =
789 RegistrationInfo_QueryInterface,
790 RegistrationInfo_AddRef,
791 RegistrationInfo_Release,
792 RegistrationInfo_GetTypeInfoCount,
793 RegistrationInfo_GetTypeInfo,
794 RegistrationInfo_GetIDsOfNames,
795 RegistrationInfo_Invoke,
796 RegistrationInfo_get_Description,
797 RegistrationInfo_put_Description,
798 RegistrationInfo_get_Author,
799 RegistrationInfo_put_Author,
800 RegistrationInfo_get_Version,
801 RegistrationInfo_put_Version,
802 RegistrationInfo_get_Date,
803 RegistrationInfo_put_Date,
804 RegistrationInfo_get_Documentation,
805 RegistrationInfo_put_Documentation,
806 RegistrationInfo_get_XmlText,
807 RegistrationInfo_put_XmlText,
808 RegistrationInfo_get_URI,
809 RegistrationInfo_put_URI,
810 RegistrationInfo_get_SecurityDescriptor,
811 RegistrationInfo_put_SecurityDescriptor,
812 RegistrationInfo_get_Source,
813 RegistrationInfo_put_Source
816 static HRESULT RegistrationInfo_create(IRegistrationInfo **obj)
818 registration_info *reginfo;
820 reginfo = heap_alloc_zero(sizeof(*reginfo));
821 if (!reginfo) return E_OUTOFMEMORY;
823 reginfo->IRegistrationInfo_iface.lpVtbl = &RegistrationInfo_vtbl;
824 reginfo->ref = 1;
825 *obj = &reginfo->IRegistrationInfo_iface;
827 TRACE("created %p\n", *obj);
829 return S_OK;
832 typedef struct
834 ITaskSettings ITaskSettings_iface;
835 LONG ref;
836 WCHAR *restart_interval;
837 WCHAR *execution_time_limit;
838 WCHAR *delete_expired_task_after;
839 int restart_count;
840 int priority;
841 TASK_INSTANCES_POLICY policy;
842 TASK_COMPATIBILITY compatibility;
843 BOOL allow_on_demand_start;
844 BOOL stop_if_going_on_batteries;
845 BOOL disallow_start_if_on_batteries;
846 BOOL allow_hard_terminate;
847 BOOL start_when_available;
848 BOOL run_only_if_network_available;
849 BOOL enabled;
850 BOOL hidden;
851 BOOL run_only_if_idle;
852 BOOL wake_to_run;
853 } TaskSettings;
855 static inline TaskSettings *impl_from_ITaskSettings(ITaskSettings *iface)
857 return CONTAINING_RECORD(iface, TaskSettings, ITaskSettings_iface);
860 static ULONG WINAPI TaskSettings_AddRef(ITaskSettings *iface)
862 TaskSettings *taskset = impl_from_ITaskSettings(iface);
863 return InterlockedIncrement(&taskset->ref);
866 static ULONG WINAPI TaskSettings_Release(ITaskSettings *iface)
868 TaskSettings *taskset = impl_from_ITaskSettings(iface);
869 LONG ref = InterlockedDecrement(&taskset->ref);
871 if (!ref)
873 TRACE("destroying %p\n", iface);
874 heap_free(taskset->restart_interval);
875 heap_free(taskset->execution_time_limit);
876 heap_free(taskset->delete_expired_task_after);
877 heap_free(taskset);
880 return ref;
883 static HRESULT WINAPI TaskSettings_QueryInterface(ITaskSettings *iface, REFIID riid, void **obj)
885 if (!riid || !obj) return E_INVALIDARG;
887 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
889 if (IsEqualGUID(riid, &IID_ITaskSettings) ||
890 IsEqualGUID(riid, &IID_IDispatch) ||
891 IsEqualGUID(riid, &IID_IUnknown))
893 ITaskSettings_AddRef(iface);
894 *obj = iface;
895 return S_OK;
898 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
899 *obj = NULL;
900 return E_NOINTERFACE;
903 static HRESULT WINAPI TaskSettings_GetTypeInfoCount(ITaskSettings *iface, UINT *count)
905 FIXME("%p,%p: stub\n", iface, count);
906 return E_NOTIMPL;
909 static HRESULT WINAPI TaskSettings_GetTypeInfo(ITaskSettings *iface, UINT index, LCID lcid, ITypeInfo **info)
911 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
912 return E_NOTIMPL;
915 static HRESULT WINAPI TaskSettings_GetIDsOfNames(ITaskSettings *iface, REFIID riid, LPOLESTR *names,
916 UINT count, LCID lcid, DISPID *dispid)
918 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
919 return E_NOTIMPL;
922 static HRESULT WINAPI TaskSettings_Invoke(ITaskSettings *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
923 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
925 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
926 params, result, excepinfo, argerr);
927 return E_NOTIMPL;
930 static HRESULT WINAPI TaskSettings_get_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL *allow)
932 TaskSettings *taskset = impl_from_ITaskSettings(iface);
934 TRACE("%p,%p\n", iface, allow);
936 if (!allow) return E_POINTER;
938 *allow = taskset->allow_on_demand_start ? VARIANT_TRUE : VARIANT_FALSE;
940 return S_OK;
943 static HRESULT WINAPI TaskSettings_put_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL allow)
945 TaskSettings *taskset = impl_from_ITaskSettings(iface);
947 TRACE("%p,%d\n", iface, allow);
949 taskset->allow_on_demand_start = allow ? TRUE : FALSE;
951 return S_OK;
954 static HRESULT WINAPI TaskSettings_get_RestartInterval(ITaskSettings *iface, BSTR *interval)
956 TaskSettings *taskset = impl_from_ITaskSettings(iface);
958 TRACE("%p,%p\n", iface, interval);
960 if (!interval) return E_POINTER;
962 if (!taskset->restart_interval)
964 *interval = NULL;
965 return S_OK;
968 if (!taskset->restart_interval) *interval = NULL;
969 else if (!(*interval = SysAllocString(taskset->restart_interval))) return E_OUTOFMEMORY;
971 return S_OK;
974 static HRESULT WINAPI TaskSettings_put_RestartInterval(ITaskSettings *iface, BSTR interval)
976 TaskSettings *taskset = impl_from_ITaskSettings(iface);
977 WCHAR *str = NULL;
979 TRACE("%p,%s\n", iface, debugstr_w(interval));
981 if (interval && !(str = heap_strdupW(interval))) return E_OUTOFMEMORY;
982 heap_free(taskset->restart_interval);
983 taskset->restart_interval = str;
985 return S_OK;
988 static HRESULT WINAPI TaskSettings_get_RestartCount(ITaskSettings *iface, INT *count)
990 TaskSettings *taskset = impl_from_ITaskSettings(iface);
992 TRACE("%p,%p\n", iface, count);
994 if (!count) return E_POINTER;
996 *count = taskset->restart_count;
998 return S_OK;
1001 static HRESULT WINAPI TaskSettings_put_RestartCount(ITaskSettings *iface, INT count)
1003 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1005 TRACE("%p,%d\n", iface, count);
1007 taskset->restart_count = count;
1009 return S_OK;
1012 static HRESULT WINAPI TaskSettings_get_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY *policy)
1014 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1016 TRACE("%p,%p\n", iface, policy);
1018 if (!policy) return E_POINTER;
1020 *policy = taskset->policy;
1022 return S_OK;
1025 static HRESULT WINAPI TaskSettings_put_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY policy)
1027 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1029 TRACE("%p,%d\n", iface, policy);
1031 taskset->policy = policy;
1033 return S_OK;
1036 static HRESULT WINAPI TaskSettings_get_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL *stop)
1038 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1040 TRACE("%p,%p\n", iface, stop);
1042 if (!stop) return E_POINTER;
1044 *stop = taskset->stop_if_going_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1046 return S_OK;
1049 static HRESULT WINAPI TaskSettings_put_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL stop)
1051 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1053 TRACE("%p,%d\n", iface, stop);
1055 taskset->stop_if_going_on_batteries = stop ? TRUE : FALSE;
1057 return S_OK;
1060 static HRESULT WINAPI TaskSettings_get_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL *disallow)
1062 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1064 TRACE("%p,%p\n", iface, disallow);
1066 if (!disallow) return E_POINTER;
1068 *disallow = taskset->disallow_start_if_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1070 return S_OK;
1073 static HRESULT WINAPI TaskSettings_put_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL disallow)
1075 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1077 TRACE("%p,%d\n", iface, disallow);
1079 taskset->disallow_start_if_on_batteries = disallow ? TRUE : FALSE;
1081 return S_OK;
1084 static HRESULT WINAPI TaskSettings_get_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL *allow)
1086 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1088 TRACE("%p,%p\n", iface, allow);
1090 if (!allow) return E_POINTER;
1092 *allow = taskset->allow_hard_terminate ? VARIANT_TRUE : VARIANT_FALSE;
1094 return S_OK;
1097 static HRESULT WINAPI TaskSettings_put_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL allow)
1099 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1101 TRACE("%p,%d\n", iface, allow);
1103 taskset->allow_hard_terminate = allow ? TRUE : FALSE;
1105 return S_OK;
1108 static HRESULT WINAPI TaskSettings_get_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL *start)
1110 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1112 TRACE("%p,%p\n", iface, start);
1114 if (!start) return E_POINTER;
1116 *start = taskset->start_when_available ? VARIANT_TRUE : VARIANT_FALSE;
1118 return S_OK;
1121 static HRESULT WINAPI TaskSettings_put_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL start)
1123 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1125 TRACE("%p,%d\n", iface, start);
1127 taskset->start_when_available = start ? TRUE : FALSE;
1129 return S_OK;
1132 static HRESULT WINAPI TaskSettings_get_XmlText(ITaskSettings *iface, BSTR *xml)
1134 FIXME("%p,%p: stub\n", iface, xml);
1135 return E_NOTIMPL;
1138 static HRESULT WINAPI TaskSettings_put_XmlText(ITaskSettings *iface, BSTR xml)
1140 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
1141 return E_NOTIMPL;
1144 static HRESULT WINAPI TaskSettings_get_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL *run)
1146 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1148 TRACE("%p,%p\n", iface, run);
1150 if (!run) return E_POINTER;
1152 *run = taskset->run_only_if_network_available ? VARIANT_TRUE : VARIANT_FALSE;
1154 return S_OK;
1157 static HRESULT WINAPI TaskSettings_put_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL run)
1159 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1161 TRACE("%p,%d\n", iface, run);
1163 taskset->run_only_if_network_available = run ? TRUE : FALSE;
1165 return S_OK;
1168 static HRESULT WINAPI TaskSettings_get_ExecutionTimeLimit(ITaskSettings *iface, BSTR *limit)
1170 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1172 TRACE("%p,%p\n", iface, limit);
1174 if (!limit) return E_POINTER;
1176 if (!taskset->execution_time_limit)
1178 *limit = NULL;
1179 return S_OK;
1182 if (!taskset->execution_time_limit) *limit = NULL;
1183 else if (!(*limit = SysAllocString(taskset->execution_time_limit))) return E_OUTOFMEMORY;
1185 return S_OK;
1188 static HRESULT WINAPI TaskSettings_put_ExecutionTimeLimit(ITaskSettings *iface, BSTR limit)
1190 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1191 WCHAR *str = NULL;
1193 TRACE("%p,%s\n", iface, debugstr_w(limit));
1195 if (limit && !(str = heap_strdupW(limit))) return E_OUTOFMEMORY;
1196 heap_free(taskset->execution_time_limit);
1197 taskset->execution_time_limit = str;
1199 return S_OK;
1202 static HRESULT WINAPI TaskSettings_get_Enabled(ITaskSettings *iface, VARIANT_BOOL *enabled)
1204 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1206 TRACE("%p,%p\n", iface, enabled);
1208 if (!enabled) return E_POINTER;
1210 *enabled = taskset->enabled ? VARIANT_TRUE : VARIANT_FALSE;
1212 return S_OK;
1215 static HRESULT WINAPI TaskSettings_put_Enabled(ITaskSettings *iface, VARIANT_BOOL enabled)
1217 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1219 TRACE("%p,%d\n", iface, enabled);
1221 taskset->enabled = enabled ? TRUE : FALSE;
1223 return S_OK;
1226 static HRESULT WINAPI TaskSettings_get_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR *delay)
1228 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1230 TRACE("%p,%p\n", iface, delay);
1232 if (!delay) return E_POINTER;
1234 if (!taskset->delete_expired_task_after) *delay = NULL;
1235 else if (!(*delay = SysAllocString(taskset->delete_expired_task_after))) return E_OUTOFMEMORY;
1237 return S_OK;
1240 static HRESULT WINAPI TaskSettings_put_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR delay)
1242 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1243 WCHAR *str = NULL;
1245 TRACE("%p,%s\n", iface, debugstr_w(delay));
1247 if (delay && !(str = heap_strdupW(delay))) return E_OUTOFMEMORY;
1248 heap_free(taskset->delete_expired_task_after);
1249 taskset->delete_expired_task_after = str;
1251 return S_OK;
1254 static HRESULT WINAPI TaskSettings_get_Priority(ITaskSettings *iface, INT *priority)
1256 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1258 TRACE("%p,%p\n", iface, priority);
1260 if (!priority) return E_POINTER;
1262 *priority = taskset->priority;
1264 return S_OK;
1267 static HRESULT WINAPI TaskSettings_put_Priority(ITaskSettings *iface, INT priority)
1269 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1271 TRACE("%p,%d\n", iface, priority);
1273 taskset->priority = priority;
1275 return S_OK;
1278 static HRESULT WINAPI TaskSettings_get_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY *level)
1280 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1282 TRACE("%p,%p\n", iface, level);
1284 if (!level) return E_POINTER;
1286 *level = taskset->compatibility;
1288 return S_OK;
1291 static HRESULT WINAPI TaskSettings_put_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY level)
1293 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1295 TRACE("%p,%d\n", iface, level);
1297 taskset->compatibility = level;
1299 return S_OK;
1302 static HRESULT WINAPI TaskSettings_get_Hidden(ITaskSettings *iface, VARIANT_BOOL *hidden)
1304 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1306 TRACE("%p,%p\n", iface, hidden);
1308 if (!hidden) return E_POINTER;
1310 *hidden = taskset->hidden ? VARIANT_TRUE : VARIANT_FALSE;
1312 return S_OK;
1315 static HRESULT WINAPI TaskSettings_put_Hidden(ITaskSettings *iface, VARIANT_BOOL hidden)
1317 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1319 TRACE("%p,%d\n", iface, hidden);
1321 taskset->hidden = hidden ? TRUE : FALSE;
1323 return S_OK;
1326 static HRESULT WINAPI TaskSettings_get_IdleSettings(ITaskSettings *iface, IIdleSettings **settings)
1328 FIXME("%p,%p: stub\n", iface, settings);
1329 return E_NOTIMPL;
1332 static HRESULT WINAPI TaskSettings_put_IdleSettings(ITaskSettings *iface, IIdleSettings *settings)
1334 FIXME("%p,%p: stub\n", iface, settings);
1335 return E_NOTIMPL;
1338 static HRESULT WINAPI TaskSettings_get_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL *run)
1340 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1342 TRACE("%p,%p\n", iface, run);
1344 if (!run) return E_POINTER;
1346 *run = taskset->run_only_if_idle ? VARIANT_TRUE : VARIANT_FALSE;
1348 return S_OK;
1351 static HRESULT WINAPI TaskSettings_put_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL run)
1353 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1355 TRACE("%p,%d\n", iface, run);
1357 taskset->run_only_if_idle = run ? TRUE : FALSE;
1359 return S_OK;
1362 static HRESULT WINAPI TaskSettings_get_WakeToRun(ITaskSettings *iface, VARIANT_BOOL *wake)
1364 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1366 TRACE("%p,%p\n", iface, wake);
1368 if (!wake) return E_POINTER;
1370 *wake = taskset->wake_to_run ? VARIANT_TRUE : VARIANT_FALSE;
1372 return S_OK;
1375 static HRESULT WINAPI TaskSettings_put_WakeToRun(ITaskSettings *iface, VARIANT_BOOL wake)
1377 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1379 TRACE("%p,%d\n", iface, wake);
1381 taskset->wake_to_run = wake ? TRUE : FALSE;
1383 return S_OK;
1386 static HRESULT WINAPI TaskSettings_get_NetworkSettings(ITaskSettings *iface, INetworkSettings **settings)
1388 FIXME("%p,%p: stub\n", iface, settings);
1389 return E_NOTIMPL;
1392 static HRESULT WINAPI TaskSettings_put_NetworkSettings(ITaskSettings *iface, INetworkSettings *settings)
1394 FIXME("%p,%p: stub\n", iface, settings);
1395 return E_NOTIMPL;
1398 static const ITaskSettingsVtbl TaskSettings_vtbl =
1400 TaskSettings_QueryInterface,
1401 TaskSettings_AddRef,
1402 TaskSettings_Release,
1403 TaskSettings_GetTypeInfoCount,
1404 TaskSettings_GetTypeInfo,
1405 TaskSettings_GetIDsOfNames,
1406 TaskSettings_Invoke,
1407 TaskSettings_get_AllowDemandStart,
1408 TaskSettings_put_AllowDemandStart,
1409 TaskSettings_get_RestartInterval,
1410 TaskSettings_put_RestartInterval,
1411 TaskSettings_get_RestartCount,
1412 TaskSettings_put_RestartCount,
1413 TaskSettings_get_MultipleInstances,
1414 TaskSettings_put_MultipleInstances,
1415 TaskSettings_get_StopIfGoingOnBatteries,
1416 TaskSettings_put_StopIfGoingOnBatteries,
1417 TaskSettings_get_DisallowStartIfOnBatteries,
1418 TaskSettings_put_DisallowStartIfOnBatteries,
1419 TaskSettings_get_AllowHardTerminate,
1420 TaskSettings_put_AllowHardTerminate,
1421 TaskSettings_get_StartWhenAvailable,
1422 TaskSettings_put_StartWhenAvailable,
1423 TaskSettings_get_XmlText,
1424 TaskSettings_put_XmlText,
1425 TaskSettings_get_RunOnlyIfNetworkAvailable,
1426 TaskSettings_put_RunOnlyIfNetworkAvailable,
1427 TaskSettings_get_ExecutionTimeLimit,
1428 TaskSettings_put_ExecutionTimeLimit,
1429 TaskSettings_get_Enabled,
1430 TaskSettings_put_Enabled,
1431 TaskSettings_get_DeleteExpiredTaskAfter,
1432 TaskSettings_put_DeleteExpiredTaskAfter,
1433 TaskSettings_get_Priority,
1434 TaskSettings_put_Priority,
1435 TaskSettings_get_Compatibility,
1436 TaskSettings_put_Compatibility,
1437 TaskSettings_get_Hidden,
1438 TaskSettings_put_Hidden,
1439 TaskSettings_get_IdleSettings,
1440 TaskSettings_put_IdleSettings,
1441 TaskSettings_get_RunOnlyIfIdle,
1442 TaskSettings_put_RunOnlyIfIdle,
1443 TaskSettings_get_WakeToRun,
1444 TaskSettings_put_WakeToRun,
1445 TaskSettings_get_NetworkSettings,
1446 TaskSettings_put_NetworkSettings
1449 static HRESULT TaskSettings_create(ITaskSettings **obj)
1451 static const WCHAR exec_time_limit[] = { 'P','T','7','2','H',0 };
1452 TaskSettings *taskset;
1454 taskset = heap_alloc(sizeof(*taskset));
1455 if (!taskset) return E_OUTOFMEMORY;
1457 taskset->ITaskSettings_iface.lpVtbl = &TaskSettings_vtbl;
1458 taskset->ref = 1;
1459 /* set the defaults */
1460 taskset->restart_interval = NULL;
1461 taskset->execution_time_limit = heap_strdupW(exec_time_limit);
1462 taskset->delete_expired_task_after = NULL;
1463 taskset->restart_count = 0;
1464 taskset->priority = 7;
1465 taskset->policy = TASK_INSTANCES_IGNORE_NEW;
1466 taskset->compatibility = TASK_COMPATIBILITY_V2;
1467 taskset->allow_on_demand_start = TRUE;
1468 taskset->stop_if_going_on_batteries = TRUE;
1469 taskset->disallow_start_if_on_batteries = TRUE;
1470 taskset->allow_hard_terminate = TRUE;
1471 taskset->start_when_available = FALSE;
1472 taskset->run_only_if_network_available = FALSE;
1473 taskset->enabled = TRUE;
1474 taskset->hidden = FALSE;
1475 taskset->run_only_if_idle = FALSE;
1476 taskset->wake_to_run = FALSE;
1478 *obj = &taskset->ITaskSettings_iface;
1480 TRACE("created %p\n", *obj);
1482 return S_OK;
1485 typedef struct
1487 IPrincipal IPrincipal_iface;
1488 LONG ref;
1489 } Principal;
1491 static inline Principal *impl_from_IPrincipal(IPrincipal *iface)
1493 return CONTAINING_RECORD(iface, Principal, IPrincipal_iface);
1496 static ULONG WINAPI Principal_AddRef(IPrincipal *iface)
1498 Principal *principal = impl_from_IPrincipal(iface);
1499 return InterlockedIncrement(&principal->ref);
1502 static ULONG WINAPI Principal_Release(IPrincipal *iface)
1504 Principal *principal = impl_from_IPrincipal(iface);
1505 LONG ref = InterlockedDecrement(&principal->ref);
1507 if (!ref)
1509 TRACE("destroying %p\n", iface);
1510 heap_free(principal);
1513 return ref;
1516 static HRESULT WINAPI Principal_QueryInterface(IPrincipal *iface, REFIID riid, void **obj)
1518 if (!riid || !obj) return E_INVALIDARG;
1520 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1522 if (IsEqualGUID(riid, &IID_IPrincipal) ||
1523 IsEqualGUID(riid, &IID_IDispatch) ||
1524 IsEqualGUID(riid, &IID_IUnknown))
1526 IPrincipal_AddRef(iface);
1527 *obj = iface;
1528 return S_OK;
1531 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1532 *obj = NULL;
1533 return E_NOINTERFACE;
1536 static HRESULT WINAPI Principal_GetTypeInfoCount(IPrincipal *iface, UINT *count)
1538 FIXME("%p,%p: stub\n", iface, count);
1539 return E_NOTIMPL;
1542 static HRESULT WINAPI Principal_GetTypeInfo(IPrincipal *iface, UINT index, LCID lcid, ITypeInfo **info)
1544 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1545 return E_NOTIMPL;
1548 static HRESULT WINAPI Principal_GetIDsOfNames(IPrincipal *iface, REFIID riid, LPOLESTR *names,
1549 UINT count, LCID lcid, DISPID *dispid)
1551 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1552 return E_NOTIMPL;
1555 static HRESULT WINAPI Principal_Invoke(IPrincipal *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1556 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1558 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1559 params, result, excepinfo, argerr);
1560 return E_NOTIMPL;
1563 static HRESULT WINAPI Principal_get_Id(IPrincipal *iface, BSTR *id)
1565 FIXME("%p,%p: stub\n", iface, id);
1566 return E_NOTIMPL;
1569 static HRESULT WINAPI Principal_put_Id(IPrincipal *iface, BSTR id)
1571 FIXME("%p,%s: stub\n", iface, debugstr_w(id));
1572 return S_OK;
1575 static HRESULT WINAPI Principal_get_DisplayName(IPrincipal *iface, BSTR *name)
1577 FIXME("%p,%p: stub\n", iface, name);
1578 return E_NOTIMPL;
1581 static HRESULT WINAPI Principal_put_DisplayName(IPrincipal *iface, BSTR name)
1583 FIXME("%p,%s: stub\n", iface, debugstr_w(name));
1584 return E_NOTIMPL;
1587 static HRESULT WINAPI Principal_get_UserId(IPrincipal *iface, BSTR *user_id)
1589 FIXME("%p,%p: stub\n", iface, user_id);
1590 return E_NOTIMPL;
1593 static HRESULT WINAPI Principal_put_UserId(IPrincipal *iface, BSTR user_id)
1595 FIXME("%p,%s: stub\n", iface, debugstr_w(user_id));
1596 return S_OK;
1599 static HRESULT WINAPI Principal_get_LogonType(IPrincipal *iface, TASK_LOGON_TYPE *logon_type)
1601 FIXME("%p,%p: stub\n", iface, logon_type);
1602 return E_NOTIMPL;
1605 static HRESULT WINAPI Principal_put_LogonType(IPrincipal *iface, TASK_LOGON_TYPE logon_type)
1607 FIXME("%p,%u: stub\n", iface, logon_type);
1608 return E_NOTIMPL;
1611 static HRESULT WINAPI Principal_get_GroupId(IPrincipal *iface, BSTR *group_id)
1613 FIXME("%p,%p: stub\n", iface, group_id);
1614 return E_NOTIMPL;
1617 static HRESULT WINAPI Principal_put_GroupId(IPrincipal *iface, BSTR group_id)
1619 FIXME("%p,%s: stub\n", iface, debugstr_w(group_id));
1620 return E_NOTIMPL;
1623 static HRESULT WINAPI Principal_get_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE *run_level)
1625 FIXME("%p,%p: stub\n", iface, run_level);
1626 return E_NOTIMPL;
1629 static HRESULT WINAPI Principal_put_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE run_level)
1631 FIXME("%p,%u: stub\n", iface, run_level);
1632 return E_NOTIMPL;
1635 static const IPrincipalVtbl Principal_vtbl =
1637 Principal_QueryInterface,
1638 Principal_AddRef,
1639 Principal_Release,
1640 Principal_GetTypeInfoCount,
1641 Principal_GetTypeInfo,
1642 Principal_GetIDsOfNames,
1643 Principal_Invoke,
1644 Principal_get_Id,
1645 Principal_put_Id,
1646 Principal_get_DisplayName,
1647 Principal_put_DisplayName,
1648 Principal_get_UserId,
1649 Principal_put_UserId,
1650 Principal_get_LogonType,
1651 Principal_put_LogonType,
1652 Principal_get_GroupId,
1653 Principal_put_GroupId,
1654 Principal_get_RunLevel,
1655 Principal_put_RunLevel
1658 static HRESULT Principal_create(IPrincipal **obj)
1660 Principal *principal;
1662 principal = heap_alloc(sizeof(*principal));
1663 if (!principal) return E_OUTOFMEMORY;
1665 principal->IPrincipal_iface.lpVtbl = &Principal_vtbl;
1666 principal->ref = 1;
1668 *obj = &principal->IPrincipal_iface;
1670 TRACE("created %p\n", *obj);
1672 return S_OK;
1675 typedef struct
1677 IExecAction IExecAction_iface;
1678 LONG ref;
1679 WCHAR *path;
1680 } ExecAction;
1682 static inline ExecAction *impl_from_IExecAction(IExecAction *iface)
1684 return CONTAINING_RECORD(iface, ExecAction, IExecAction_iface);
1687 static ULONG WINAPI ExecAction_AddRef(IExecAction *iface)
1689 ExecAction *action = impl_from_IExecAction(iface);
1690 return InterlockedIncrement(&action->ref);
1693 static ULONG WINAPI ExecAction_Release(IExecAction *iface)
1695 ExecAction *action = impl_from_IExecAction(iface);
1696 LONG ref = InterlockedDecrement(&action->ref);
1698 if (!ref)
1700 TRACE("destroying %p\n", iface);
1701 heap_free(action->path);
1702 heap_free(action);
1705 return ref;
1708 static HRESULT WINAPI ExecAction_QueryInterface(IExecAction *iface, REFIID riid, void **obj)
1710 if (!riid || !obj) return E_INVALIDARG;
1712 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1714 if (IsEqualGUID(riid, &IID_IExecAction) ||
1715 IsEqualGUID(riid, &IID_IAction) ||
1716 IsEqualGUID(riid, &IID_IDispatch) ||
1717 IsEqualGUID(riid, &IID_IUnknown))
1719 IExecAction_AddRef(iface);
1720 *obj = iface;
1721 return S_OK;
1724 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1725 *obj = NULL;
1726 return E_NOINTERFACE;
1729 static HRESULT WINAPI ExecAction_GetTypeInfoCount(IExecAction *iface, UINT *count)
1731 FIXME("%p,%p: stub\n", iface, count);
1732 return E_NOTIMPL;
1735 static HRESULT WINAPI ExecAction_GetTypeInfo(IExecAction *iface, UINT index, LCID lcid, ITypeInfo **info)
1737 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1738 return E_NOTIMPL;
1741 static HRESULT WINAPI ExecAction_GetIDsOfNames(IExecAction *iface, REFIID riid, LPOLESTR *names,
1742 UINT count, LCID lcid, DISPID *dispid)
1744 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1745 return E_NOTIMPL;
1748 static HRESULT WINAPI ExecAction_Invoke(IExecAction *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1749 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1751 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1752 params, result, excepinfo, argerr);
1753 return E_NOTIMPL;
1756 static HRESULT WINAPI ExecAction_get_Id(IExecAction *iface, BSTR *id)
1758 FIXME("%p,%p: stub\n", iface, id);
1759 return E_NOTIMPL;
1762 static HRESULT WINAPI ExecAction_put_Id(IExecAction *iface, BSTR id)
1764 FIXME("%p,%s: stub\n", iface, debugstr_w(id));
1765 return E_NOTIMPL;
1768 static HRESULT WINAPI ExecAction_get_Type(IExecAction *iface, TASK_ACTION_TYPE *type)
1770 TRACE("%p,%p\n", iface, type);
1772 if (!type) return E_POINTER;
1774 *type = TASK_ACTION_EXEC;
1776 return S_OK;
1779 static HRESULT WINAPI ExecAction_get_Path(IExecAction *iface, BSTR *path)
1781 ExecAction *action = impl_from_IExecAction(iface);
1783 TRACE("%p,%p\n", iface, path);
1785 if (!path) return E_POINTER;
1787 if (!action->path) *path = NULL;
1788 else if (!(*path = SysAllocString(action->path))) return E_OUTOFMEMORY;
1790 return S_OK;
1793 static HRESULT WINAPI ExecAction_put_Path(IExecAction *iface, BSTR path)
1795 ExecAction *action = impl_from_IExecAction(iface);
1796 WCHAR *str = NULL;
1798 TRACE("%p,%s\n", iface, debugstr_w(path));
1800 if (path && !(str = heap_strdupW((path)))) return E_OUTOFMEMORY;
1801 heap_free(action->path);
1802 action->path = str;
1804 return S_OK;
1807 static HRESULT WINAPI ExecAction_get_Arguments(IExecAction *iface, BSTR *arguments)
1809 FIXME("%p,%p: stub\n", iface, arguments);
1810 return E_NOTIMPL;
1813 static HRESULT WINAPI ExecAction_put_Arguments(IExecAction *iface, BSTR arguments)
1815 FIXME("%p,%s: stub\n", iface, debugstr_w(arguments));
1816 return S_OK;
1819 static HRESULT WINAPI ExecAction_get_WorkingDirectory(IExecAction *iface, BSTR *directory)
1821 FIXME("%p,%p: stub\n", iface, directory);
1822 return E_NOTIMPL;
1825 static HRESULT WINAPI ExecAction_put_WorkingDirectory(IExecAction *iface, BSTR directory)
1827 FIXME("%p,%s: stub\n", iface, debugstr_w(directory));
1828 return E_NOTIMPL;
1831 static const IExecActionVtbl Action_vtbl =
1833 ExecAction_QueryInterface,
1834 ExecAction_AddRef,
1835 ExecAction_Release,
1836 ExecAction_GetTypeInfoCount,
1837 ExecAction_GetTypeInfo,
1838 ExecAction_GetIDsOfNames,
1839 ExecAction_Invoke,
1840 ExecAction_get_Id,
1841 ExecAction_put_Id,
1842 ExecAction_get_Type,
1843 ExecAction_get_Path,
1844 ExecAction_put_Path,
1845 ExecAction_get_Arguments,
1846 ExecAction_put_Arguments,
1847 ExecAction_get_WorkingDirectory,
1848 ExecAction_put_WorkingDirectory
1851 static HRESULT ExecAction_create(IExecAction **obj)
1853 ExecAction *action;
1855 action = heap_alloc(sizeof(*action));
1856 if (!action) return E_OUTOFMEMORY;
1858 action->IExecAction_iface.lpVtbl = &Action_vtbl;
1859 action->ref = 1;
1860 action->path = NULL;
1862 *obj = &action->IExecAction_iface;
1864 TRACE("created %p\n", *obj);
1866 return S_OK;
1869 typedef struct
1871 IActionCollection IActionCollection_iface;
1872 LONG ref;
1873 } Actions;
1875 static inline Actions *impl_from_IActionCollection(IActionCollection *iface)
1877 return CONTAINING_RECORD(iface, Actions, IActionCollection_iface);
1880 static ULONG WINAPI Actions_AddRef(IActionCollection *iface)
1882 Actions *actions = impl_from_IActionCollection(iface);
1883 return InterlockedIncrement(&actions->ref);
1886 static ULONG WINAPI Actions_Release(IActionCollection *iface)
1888 Actions *actions = impl_from_IActionCollection(iface);
1889 LONG ref = InterlockedDecrement(&actions->ref);
1891 if (!ref)
1893 TRACE("destroying %p\n", iface);
1894 heap_free(actions);
1897 return ref;
1900 static HRESULT WINAPI Actions_QueryInterface(IActionCollection *iface, REFIID riid, void **obj)
1902 if (!riid || !obj) return E_INVALIDARG;
1904 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1906 if (IsEqualGUID(riid, &IID_IActionCollection) ||
1907 IsEqualGUID(riid, &IID_IDispatch) ||
1908 IsEqualGUID(riid, &IID_IUnknown))
1910 IActionCollection_AddRef(iface);
1911 *obj = iface;
1912 return S_OK;
1915 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1916 *obj = NULL;
1917 return E_NOINTERFACE;
1920 static HRESULT WINAPI Actions_GetTypeInfoCount(IActionCollection *iface, UINT *count)
1922 FIXME("%p,%p: stub\n", iface, count);
1923 return E_NOTIMPL;
1926 static HRESULT WINAPI Actions_GetTypeInfo(IActionCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
1928 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1929 return E_NOTIMPL;
1932 static HRESULT WINAPI Actions_GetIDsOfNames(IActionCollection *iface, REFIID riid, LPOLESTR *names,
1933 UINT count, LCID lcid, DISPID *dispid)
1935 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1936 return E_NOTIMPL;
1939 static HRESULT WINAPI Actions_Invoke(IActionCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1940 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1942 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1943 params, result, excepinfo, argerr);
1944 return E_NOTIMPL;
1947 static HRESULT WINAPI Actions_get_Count(IActionCollection *iface, LONG *count)
1949 FIXME("%p,%p: stub\n", iface, count);
1950 return E_NOTIMPL;
1953 static HRESULT WINAPI Actions_get_Item(IActionCollection *iface, LONG index, IAction **action)
1955 FIXME("%p,%d,%p: stub\n", iface, index, action);
1956 return E_NOTIMPL;
1959 static HRESULT WINAPI Actions_get__NewEnum(IActionCollection *iface, IUnknown **penum)
1961 FIXME("%p,%p: stub\n", iface, penum);
1962 return E_NOTIMPL;
1965 static HRESULT WINAPI Actions_get_XmlText(IActionCollection *iface, BSTR *xml)
1967 FIXME("%p,%p: stub\n", iface, xml);
1968 return E_NOTIMPL;
1971 static HRESULT WINAPI Actions_put_XmlText(IActionCollection *iface, BSTR xml)
1973 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
1974 return E_NOTIMPL;
1977 static HRESULT WINAPI Actions_Create(IActionCollection *iface, TASK_ACTION_TYPE type, IAction **action)
1979 TRACE("%p,%u,%p\n", iface, type, action);
1981 switch (type)
1983 case TASK_ACTION_EXEC:
1984 return ExecAction_create((IExecAction **)action);
1986 default:
1987 FIXME("unimplemented type %u\n", type);
1988 return E_NOTIMPL;
1992 static HRESULT WINAPI Actions_Remove(IActionCollection *iface, VARIANT index)
1994 FIXME("%p,%s: stub\n", iface, debugstr_variant(&index));
1995 return E_NOTIMPL;
1998 static HRESULT WINAPI Actions_Clear(IActionCollection *iface)
2000 FIXME("%p: stub\n", iface);
2001 return E_NOTIMPL;
2004 static HRESULT WINAPI Actions_get_Context(IActionCollection *iface, BSTR *ctx)
2006 FIXME("%p,%p: stub\n", iface, ctx);
2007 return E_NOTIMPL;
2010 static HRESULT WINAPI Actions_put_Context(IActionCollection *iface, BSTR ctx)
2012 FIXME("%p,%s: stub\n", iface, debugstr_w(ctx));
2013 return S_OK;
2016 static const IActionCollectionVtbl Actions_vtbl =
2018 Actions_QueryInterface,
2019 Actions_AddRef,
2020 Actions_Release,
2021 Actions_GetTypeInfoCount,
2022 Actions_GetTypeInfo,
2023 Actions_GetIDsOfNames,
2024 Actions_Invoke,
2025 Actions_get_Count,
2026 Actions_get_Item,
2027 Actions_get__NewEnum,
2028 Actions_get_XmlText,
2029 Actions_put_XmlText,
2030 Actions_Create,
2031 Actions_Remove,
2032 Actions_Clear,
2033 Actions_get_Context,
2034 Actions_put_Context
2037 static HRESULT Actions_create(IActionCollection **obj)
2039 Actions *actions;
2041 actions = heap_alloc(sizeof(*actions));
2042 if (!actions) return E_OUTOFMEMORY;
2044 actions->IActionCollection_iface.lpVtbl = &Actions_vtbl;
2045 actions->ref = 1;
2047 *obj = &actions->IActionCollection_iface;
2049 TRACE("created %p\n", *obj);
2051 return S_OK;
2054 typedef struct
2056 ITaskDefinition ITaskDefinition_iface;
2057 LONG ref;
2058 IRegistrationInfo *reginfo;
2059 ITaskSettings *taskset;
2060 ITriggerCollection *triggers;
2061 IPrincipal *principal;
2062 IActionCollection *actions;
2063 } TaskDefinition;
2065 static inline TaskDefinition *impl_from_ITaskDefinition(ITaskDefinition *iface)
2067 return CONTAINING_RECORD(iface, TaskDefinition, ITaskDefinition_iface);
2070 static ULONG WINAPI TaskDefinition_AddRef(ITaskDefinition *iface)
2072 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2073 return InterlockedIncrement(&taskdef->ref);
2076 static ULONG WINAPI TaskDefinition_Release(ITaskDefinition *iface)
2078 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2079 LONG ref = InterlockedDecrement(&taskdef->ref);
2081 if (!ref)
2083 TRACE("destroying %p\n", iface);
2085 if (taskdef->reginfo)
2086 IRegistrationInfo_Release(taskdef->reginfo);
2087 if (taskdef->taskset)
2088 ITaskSettings_Release(taskdef->taskset);
2089 if (taskdef->triggers)
2090 ITriggerCollection_Release(taskdef->triggers);
2091 if (taskdef->principal)
2092 IPrincipal_Release(taskdef->principal);
2093 if (taskdef->actions)
2094 IActionCollection_Release(taskdef->actions);
2096 heap_free(taskdef);
2099 return ref;
2102 static HRESULT WINAPI TaskDefinition_QueryInterface(ITaskDefinition *iface, REFIID riid, void **obj)
2104 if (!riid || !obj) return E_INVALIDARG;
2106 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
2108 if (IsEqualGUID(riid, &IID_ITaskDefinition) ||
2109 IsEqualGUID(riid, &IID_IDispatch) ||
2110 IsEqualGUID(riid, &IID_IUnknown))
2112 ITaskDefinition_AddRef(iface);
2113 *obj = iface;
2114 return S_OK;
2117 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
2118 *obj = NULL;
2119 return E_NOINTERFACE;
2122 static HRESULT WINAPI TaskDefinition_GetTypeInfoCount(ITaskDefinition *iface, UINT *count)
2124 FIXME("%p,%p: stub\n", iface, count);
2125 return E_NOTIMPL;
2128 static HRESULT WINAPI TaskDefinition_GetTypeInfo(ITaskDefinition *iface, UINT index, LCID lcid, ITypeInfo **info)
2130 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
2131 return E_NOTIMPL;
2134 static HRESULT WINAPI TaskDefinition_GetIDsOfNames(ITaskDefinition *iface, REFIID riid, LPOLESTR *names,
2135 UINT count, LCID lcid, DISPID *dispid)
2137 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
2138 return E_NOTIMPL;
2141 static HRESULT WINAPI TaskDefinition_Invoke(ITaskDefinition *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
2142 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
2144 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
2145 params, result, excepinfo, argerr);
2146 return E_NOTIMPL;
2149 static HRESULT WINAPI TaskDefinition_get_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo **info)
2151 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2152 HRESULT hr;
2154 TRACE("%p,%p\n", iface, info);
2156 if (!info) return E_POINTER;
2158 if (!taskdef->reginfo)
2160 hr = RegistrationInfo_create(&taskdef->reginfo);
2161 if (hr != S_OK) return hr;
2164 IRegistrationInfo_AddRef(taskdef->reginfo);
2165 *info = taskdef->reginfo;
2167 return S_OK;
2170 static HRESULT WINAPI TaskDefinition_put_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo *info)
2172 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2174 TRACE("%p,%p\n", iface, info);
2176 if (!info) return E_POINTER;
2178 if (taskdef->reginfo)
2179 IRegistrationInfo_Release(taskdef->reginfo);
2181 IRegistrationInfo_AddRef(info);
2182 taskdef->reginfo = info;
2184 return S_OK;
2187 static HRESULT WINAPI TaskDefinition_get_Triggers(ITaskDefinition *iface, ITriggerCollection **triggers)
2189 TaskDefinition *This = impl_from_ITaskDefinition(iface);
2191 TRACE("%p,%p\n", This, triggers);
2193 if (!This->triggers)
2195 trigger_collection *collection;
2197 collection = heap_alloc(sizeof(*collection));
2198 if (!collection) return E_OUTOFMEMORY;
2200 collection->ITriggerCollection_iface.lpVtbl = &TriggerCollection_vtbl;
2201 collection->ref = 1;
2202 This->triggers = &collection->ITriggerCollection_iface;
2205 ITriggerCollection_AddRef(*triggers = This->triggers);
2206 return S_OK;
2209 static HRESULT WINAPI TaskDefinition_put_Triggers(ITaskDefinition *iface, ITriggerCollection *triggers)
2211 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2213 TRACE("%p,%p\n", iface, triggers);
2215 if (!triggers) return E_POINTER;
2217 if (taskdef->triggers)
2218 ITriggerCollection_Release(taskdef->triggers);
2220 ITriggerCollection_AddRef(triggers);
2221 taskdef->triggers = triggers;
2223 return S_OK;
2226 static HRESULT WINAPI TaskDefinition_get_Settings(ITaskDefinition *iface, ITaskSettings **settings)
2228 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2229 HRESULT hr;
2231 TRACE("%p,%p\n", iface, settings);
2233 if (!settings) return E_POINTER;
2235 if (!taskdef->taskset)
2237 hr = TaskSettings_create(&taskdef->taskset);
2238 if (hr != S_OK) return hr;
2241 ITaskSettings_AddRef(taskdef->taskset);
2242 *settings = taskdef->taskset;
2244 return S_OK;
2247 static HRESULT WINAPI TaskDefinition_put_Settings(ITaskDefinition *iface, ITaskSettings *settings)
2249 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2251 TRACE("%p,%p\n", iface, settings);
2253 if (!settings) return E_POINTER;
2255 if (taskdef->taskset)
2256 ITaskSettings_Release(taskdef->taskset);
2258 ITaskSettings_AddRef(settings);
2259 taskdef->taskset = settings;
2261 return S_OK;
2264 static HRESULT WINAPI TaskDefinition_get_Data(ITaskDefinition *iface, BSTR *data)
2266 FIXME("%p,%p: stub\n", iface, data);
2267 return E_NOTIMPL;
2270 static HRESULT WINAPI TaskDefinition_put_Data(ITaskDefinition *iface, BSTR data)
2272 FIXME("%p,%p: stub\n", iface, data);
2273 return E_NOTIMPL;
2276 static HRESULT WINAPI TaskDefinition_get_Principal(ITaskDefinition *iface, IPrincipal **principal)
2278 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2279 HRESULT hr;
2281 TRACE("%p,%p\n", iface, principal);
2283 if (!principal) return E_POINTER;
2285 if (!taskdef->principal)
2287 hr = Principal_create(&taskdef->principal);
2288 if (hr != S_OK) return hr;
2291 IPrincipal_AddRef(taskdef->principal);
2292 *principal = taskdef->principal;
2294 return S_OK;
2297 static HRESULT WINAPI TaskDefinition_put_Principal(ITaskDefinition *iface, IPrincipal *principal)
2299 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2301 TRACE("%p,%p\n", iface, principal);
2303 if (!principal) return E_POINTER;
2305 if (taskdef->principal)
2306 IPrincipal_Release(taskdef->principal);
2308 IPrincipal_AddRef(principal);
2309 taskdef->principal = principal;
2311 return S_OK;
2314 static HRESULT WINAPI TaskDefinition_get_Actions(ITaskDefinition *iface, IActionCollection **actions)
2316 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2317 HRESULT hr;
2319 TRACE("%p,%p\n", iface, actions);
2321 if (!actions) return E_POINTER;
2323 if (!taskdef->actions)
2325 hr = Actions_create(&taskdef->actions);
2326 if (hr != S_OK) return hr;
2329 IActionCollection_AddRef(taskdef->actions);
2330 *actions = taskdef->actions;
2332 return S_OK;
2335 static HRESULT WINAPI TaskDefinition_put_Actions(ITaskDefinition *iface, IActionCollection *actions)
2337 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2339 TRACE("%p,%p\n", iface, actions);
2341 if (!actions) return E_POINTER;
2343 if (taskdef->actions)
2344 IActionCollection_Release(taskdef->actions);
2346 IActionCollection_AddRef(actions);
2347 taskdef->actions = actions;
2349 return S_OK;
2352 static const WCHAR Task[] = {'T','a','s','k',0};
2353 static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
2354 static const WCHAR v1_0[] = {'1','.','0',0};
2355 static const WCHAR v1_1[] = {'1','.','1',0};
2356 static const WCHAR v1_2[] = {'1','.','2',0};
2357 static const WCHAR v1_3[] = {'1','.','3',0};
2358 static const WCHAR xmlns[] = {'x','m','l','n','s',0};
2359 static const WCHAR task_ns[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','w','i','n','d','o','w','s','/','2','0','0','4','/','0','2','/','m','i','t','/','t','a','s','k',0};
2360 static const WCHAR RegistrationInfo[] = {'R','e','g','i','s','t','r','a','t','i','o','n','I','n','f','o',0};
2361 static const WCHAR Author[] = {'A','u','t','h','o','r',0};
2362 static const WCHAR Description[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
2363 static const WCHAR Source[] = {'S','o','u','r','c','e',0};
2364 static const WCHAR Date[] = {'D','a','t','e',0};
2365 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
2366 static const WCHAR Documentation[] = {'D','o','c','u','m','e','n','t','a','t','i','o','n',0};
2367 static const WCHAR URI[] = {'U','R','I',0};
2368 static const WCHAR SecurityDescriptor[] = {'S','e','c','u','r','i','t','y','D','e','s','c','r','i','p','t','o','r',0};
2369 static const WCHAR Settings[] = {'S','e','t','t','i','n','g','s',0};
2370 static const WCHAR Triggers[] = {'T','r','i','g','g','e','r','s',0};
2371 static const WCHAR Principals[] = {'P','r','i','n','c','i','p','a','l','s',0};
2372 static const WCHAR principalW[] = {'P','r','i','n','c','i','p','a','l',0};
2373 static const WCHAR id[] = {'i','d',0};
2374 static const WCHAR UserId[] = {'U','s','e','r','I','d',0};
2375 static const WCHAR LogonType[] = {'L','o','g','o','n','T','y','p','e',0};
2376 static const WCHAR GroupId[] = {'G','r','o','u','p','I','d',0};
2377 static const WCHAR DisplayName[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
2378 static const WCHAR HighestAvailable[] = {'H','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
2379 static const WCHAR Password[] = {'P','a','s','s','w','o','r','d',0};
2380 static const WCHAR S4U[] = {'S','4','U',0};
2381 static const WCHAR InteractiveToken[] = {'I','n','t','e','r','a','c','t','i','v','e','T','o','k','e','n',0};
2382 static const WCHAR RunLevel[] = {'R','u','n','L','e','v','e','l',0};
2383 static const WCHAR LeastPrivilege[] = {'L','e','a','s','t','P','r','i','v','i','l','e','g','e',0};
2384 static const WCHAR actionsW[] = {'A','c','t','i','o','n','s',0};
2385 static const WCHAR Exec[] = {'E','x','e','c',0};
2386 static const WCHAR MultipleInstancesPolicy[] = {'M','u','l','t','i','p','l','e','I','n','s','t','a','n','c','e','s','P','o','l','i','c','y',0};
2387 static const WCHAR IgnoreNew[] = {'I','g','n','o','r','e','N','e','w',0};
2388 static const WCHAR DisallowStartIfOnBatteries[] = {'D','i','s','a','l','l','o','w','S','t','a','r','t','I','f','O','n','B','a','t','t','e','r','i','e','s',0};
2389 static const WCHAR AllowStartOnDemand[] = {'A','l','l','o','w','S','t','a','r','t','O','n','D','e','m','a','n','d',0};
2390 static const WCHAR StopIfGoingOnBatteries[] = {'S','t','o','p','I','f','G','o','i','n','g','O','n','B','a','t','t','e','r','i','e','s',0};
2391 static const WCHAR AllowHardTerminate[] = {'A','l','l','o','w','H','a','r','d','T','e','r','m','i','n','a','t','e',0};
2392 static const WCHAR StartWhenAvailable[] = {'S','t','a','r','t','W','h','e','n','A','v','a','i','l','a','b','l','e',0};
2393 static const WCHAR RunOnlyIfNetworkAvailable[] = {'R','u','n','O','n','l','y','I','f','N','e','t','w','o','r','k','A','v','a','i','l','a','b','l','e',0};
2394 static const WCHAR Enabled[] = {'E','n','a','b','l','e','d',0};
2395 static const WCHAR Hidden[] = {'H','i','d','d','e','n',0};
2396 static const WCHAR RunOnlyIfIdle[] = {'R','u','n','O','n','l','y','I','f','I','d','l','e',0};
2397 static const WCHAR WakeToRun[] = {'W','a','k','e','T','o','R','u','n',0};
2398 static const WCHAR ExecutionTimeLimit[] = {'E','x','e','c','u','t','i','o','n','T','i','m','e','L','i','m','i','t',0};
2399 static const WCHAR Priority[] = {'P','r','i','o','r','i','t','y',0};
2400 static const WCHAR IdleSettings[] = {'I','d','l','e','S','e','t','t','i','n','g','s',0};
2402 static int xml_indent;
2404 static inline void push_indent(void)
2406 xml_indent += 2;
2409 static inline void pop_indent(void)
2411 xml_indent -= 2;
2414 static inline HRESULT write_stringW(IStream *stream, const WCHAR *str)
2416 return IStream_Write(stream, str, lstrlenW(str) * sizeof(WCHAR), NULL);
2419 static void write_indent(IStream *stream)
2421 static const WCHAR spacesW[] = {' ',' ',0};
2422 int i;
2423 for (i = 0; i < xml_indent; i += 2)
2424 write_stringW(stream, spacesW);
2427 static const WCHAR start_element[] = {'<',0};
2428 static const WCHAR start_end_element[] = {'<','/',0};
2429 static const WCHAR close_element[] = {'>',0};
2430 static const WCHAR end_empty_element[] = {'/','>',0};
2431 static const WCHAR eol[] = {'\n',0};
2432 static const WCHAR spaceW[] = {' ',0};
2433 static const WCHAR equalW[] = {'=',0};
2434 static const WCHAR quoteW[] = {'"',0};
2436 static inline HRESULT write_empty_element(IStream *stream, const WCHAR *name)
2438 write_indent(stream);
2439 write_stringW(stream, start_element);
2440 write_stringW(stream, name);
2441 write_stringW(stream, end_empty_element);
2442 return write_stringW(stream, eol);
2445 static inline HRESULT write_element(IStream *stream, const WCHAR *name)
2447 write_indent(stream);
2448 write_stringW(stream, start_element);
2449 write_stringW(stream, name);
2450 write_stringW(stream, close_element);
2451 return write_stringW(stream, eol);
2454 static inline HRESULT write_element_end(IStream *stream, const WCHAR *name)
2456 write_indent(stream);
2457 write_stringW(stream, start_end_element);
2458 write_stringW(stream, name);
2459 write_stringW(stream, close_element);
2460 return write_stringW(stream, eol);
2463 static inline HRESULT write_text_value(IStream *stream, const WCHAR *name, const WCHAR *value)
2465 write_indent(stream);
2466 write_stringW(stream, start_element);
2467 write_stringW(stream, name);
2468 write_stringW(stream, close_element);
2469 write_stringW(stream, value);
2470 write_stringW(stream, start_end_element);
2471 write_stringW(stream, name);
2472 write_stringW(stream, close_element);
2473 return write_stringW(stream, eol);
2476 static HRESULT write_task_attributes(IStream *stream, ITaskDefinition *taskdef)
2478 HRESULT hr;
2479 ITaskSettings *taskset;
2480 TASK_COMPATIBILITY level;
2481 const WCHAR *compatibility;
2483 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
2484 if (hr != S_OK) return hr;
2486 hr = ITaskSettings_get_Compatibility(taskset, &level);
2487 if (hr != S_OK) level = TASK_COMPATIBILITY_V2_1;
2489 ITaskSettings_Release(taskset);
2491 switch (level)
2493 case TASK_COMPATIBILITY_AT:
2494 compatibility = v1_0;
2495 break;
2496 case TASK_COMPATIBILITY_V1:
2497 compatibility = v1_1;
2498 break;
2499 case TASK_COMPATIBILITY_V2:
2500 compatibility = v1_2;
2501 break;
2502 default:
2503 compatibility = v1_3;
2504 break;
2507 write_stringW(stream, start_element);
2508 write_stringW(stream, Task);
2509 write_stringW(stream, spaceW);
2510 write_stringW(stream, version);
2511 write_stringW(stream, equalW);
2512 write_stringW(stream, quoteW);
2513 write_stringW(stream, compatibility);
2514 write_stringW(stream, quoteW);
2515 write_stringW(stream, spaceW);
2516 write_stringW(stream, xmlns);
2517 write_stringW(stream, equalW);
2518 write_stringW(stream, quoteW);
2519 write_stringW(stream, task_ns);
2520 write_stringW(stream, quoteW);
2521 write_stringW(stream, close_element);
2522 return write_stringW(stream, eol);
2525 static HRESULT write_registration_info(IStream *stream, IRegistrationInfo *reginfo)
2527 HRESULT hr;
2528 BSTR bstr;
2529 VARIANT var;
2531 if (!reginfo)
2532 return write_empty_element(stream, RegistrationInfo);
2534 hr = write_element(stream, RegistrationInfo);
2535 if (hr != S_OK) return hr;
2537 push_indent();
2539 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
2540 if (hr == S_OK && bstr)
2542 hr = write_text_value(stream, Source, bstr);
2543 SysFreeString(bstr);
2544 if (hr != S_OK) return hr;
2546 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
2547 if (hr == S_OK && bstr)
2549 hr = write_text_value(stream, Date, bstr);
2550 SysFreeString(bstr);
2551 if (hr != S_OK) return hr;
2553 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
2554 if (hr == S_OK && bstr)
2556 hr = write_text_value(stream, Author, bstr);
2557 SysFreeString(bstr);
2558 if (hr != S_OK) return hr;
2560 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
2561 if (hr == S_OK && bstr)
2563 hr = write_text_value(stream, Version, bstr);
2564 SysFreeString(bstr);
2565 if (hr != S_OK) return hr;
2567 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
2568 if (hr == S_OK && bstr)
2570 hr = write_text_value(stream, Description, bstr);
2571 SysFreeString(bstr);
2572 if (hr != S_OK) return hr;
2574 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
2575 if (hr == S_OK && bstr)
2577 hr = write_text_value(stream, Documentation, bstr);
2578 SysFreeString(bstr);
2579 if (hr != S_OK) return hr;
2581 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
2582 if (hr == S_OK && bstr)
2584 hr = write_text_value(stream, URI, bstr);
2585 SysFreeString(bstr);
2586 if (hr != S_OK) return hr;
2588 hr = IRegistrationInfo_get_SecurityDescriptor(reginfo, &var);
2589 if (hr == S_OK)
2591 if (V_VT(&var) == VT_BSTR)
2593 hr = write_text_value(stream, SecurityDescriptor, V_BSTR(&var));
2594 VariantClear(&var);
2595 if (hr != S_OK) return hr;
2597 else
2598 FIXME("SecurityInfo variant type %d is not supported\n", V_VT(&var));
2601 pop_indent();
2603 return write_element_end(stream, RegistrationInfo);
2606 static HRESULT write_principal(IStream *stream, IPrincipal *principal)
2608 HRESULT hr;
2609 BSTR bstr;
2610 TASK_LOGON_TYPE logon;
2611 TASK_RUNLEVEL_TYPE level;
2613 if (!principal)
2614 return write_empty_element(stream, Principals);
2616 hr = write_element(stream, Principals);
2617 if (hr != S_OK) return hr;
2619 push_indent();
2621 hr = IPrincipal_get_Id(principal, &bstr);
2622 if (hr == S_OK)
2624 write_indent(stream);
2625 write_stringW(stream, start_element);
2626 write_stringW(stream, principalW);
2627 write_stringW(stream, spaceW);
2628 write_stringW(stream, id);
2629 write_stringW(stream, equalW);
2630 write_stringW(stream, quoteW);
2631 write_stringW(stream, bstr);
2632 write_stringW(stream, quoteW);
2633 write_stringW(stream, close_element);
2634 write_stringW(stream, eol);
2635 SysFreeString(bstr);
2637 else
2638 write_element(stream, principalW);
2640 push_indent();
2642 hr = IPrincipal_get_GroupId(principal, &bstr);
2643 if (hr == S_OK)
2645 hr = write_text_value(stream, GroupId, bstr);
2646 SysFreeString(bstr);
2647 if (hr != S_OK) return hr;
2649 hr = IPrincipal_get_DisplayName(principal, &bstr);
2650 if (hr == S_OK)
2652 hr = write_text_value(stream, DisplayName, bstr);
2653 SysFreeString(bstr);
2654 if (hr != S_OK) return hr;
2656 hr = IPrincipal_get_UserId(principal, &bstr);
2657 if (hr == S_OK && lstrlenW(bstr))
2659 hr = write_text_value(stream, UserId, bstr);
2660 SysFreeString(bstr);
2661 if (hr != S_OK) return hr;
2663 hr = IPrincipal_get_RunLevel(principal, &level);
2664 if (hr == S_OK)
2666 const WCHAR *level_str = NULL;
2668 switch (level)
2670 case TASK_RUNLEVEL_HIGHEST:
2671 level_str = HighestAvailable;
2672 break;
2673 case TASK_RUNLEVEL_LUA:
2674 level_str = LeastPrivilege;
2675 break;
2676 default:
2677 FIXME("Principal run level %d\n", level);
2678 break;
2681 if (level_str)
2683 hr = write_text_value(stream, RunLevel, level_str);
2684 if (hr != S_OK) return hr;
2687 hr = IPrincipal_get_LogonType(principal, &logon);
2688 if (hr == S_OK)
2690 const WCHAR *logon_str = NULL;
2692 switch (logon)
2694 case TASK_LOGON_PASSWORD:
2695 logon_str = Password;
2696 break;
2697 case TASK_LOGON_S4U:
2698 logon_str = S4U;
2699 break;
2700 case TASK_LOGON_INTERACTIVE_TOKEN:
2701 logon_str = InteractiveToken;
2702 break;
2703 default:
2704 FIXME("Principal logon type %d\n", logon);
2705 break;
2708 if (logon_str)
2710 hr = write_text_value(stream, LogonType, logon_str);
2711 if (hr != S_OK) return hr;
2715 pop_indent();
2716 write_element_end(stream, principalW);
2718 pop_indent();
2719 return write_element_end(stream, Principals);
2722 static HRESULT write_settings(IStream *stream, ITaskSettings *settings)
2724 if (!settings)
2725 return write_empty_element(stream, Settings);
2727 FIXME("stub\n");
2728 return S_OK;
2731 static HRESULT write_triggers(IStream *stream, ITriggerCollection *triggers)
2733 if (!triggers)
2734 return write_empty_element(stream, Triggers);
2736 FIXME("stub\n");
2737 return S_OK;
2740 static HRESULT write_actions(IStream *stream, IActionCollection *actions)
2742 if (!actions)
2744 write_element(stream, actionsW);
2745 push_indent();
2746 write_empty_element(stream, Exec);
2747 pop_indent();
2748 return write_element_end(stream, actionsW);
2751 FIXME("stub\n");
2752 return S_OK;
2755 static HRESULT WINAPI TaskDefinition_get_XmlText(ITaskDefinition *iface, BSTR *xml)
2757 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2758 HRESULT hr;
2759 IStream *stream;
2760 HGLOBAL hmem;
2761 void *p;
2763 TRACE("%p,%p\n", iface, xml);
2765 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16);
2766 if (!hmem) return E_OUTOFMEMORY;
2768 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2769 if (hr != S_OK)
2771 GlobalFree(hmem);
2772 return hr;
2775 hr = write_task_attributes(stream, &taskdef->ITaskDefinition_iface);
2776 if (hr != S_OK) goto failed;
2778 push_indent();
2780 hr = write_registration_info(stream, taskdef->reginfo);
2781 if (hr != S_OK) goto failed;
2783 hr = write_triggers(stream, taskdef->triggers);
2784 if (hr != S_OK) goto failed;
2786 hr = write_principal(stream, taskdef->principal);
2787 if (hr != S_OK) goto failed;
2789 hr = write_settings(stream, taskdef->taskset);
2790 if (hr != S_OK) goto failed;
2792 hr = write_actions(stream, taskdef->actions);
2793 if (hr != S_OK) goto failed;
2795 pop_indent();
2797 write_element_end(stream, Task);
2798 IStream_Write(stream, "\0\0", 2, NULL);
2800 p = GlobalLock(hmem);
2801 *xml = SysAllocString(p);
2802 GlobalUnlock(hmem);
2804 IStream_Release(stream);
2806 return *xml ? S_OK : E_OUTOFMEMORY;
2808 failed:
2809 IStream_Release(stream);
2810 return hr;
2813 static HRESULT read_text_value(IXmlReader *reader, WCHAR **value)
2815 HRESULT hr;
2816 XmlNodeType type;
2818 while (IXmlReader_Read(reader, &type) == S_OK)
2820 switch (type)
2822 case XmlNodeType_Text:
2823 hr = IXmlReader_GetValue(reader, (const WCHAR **)value, NULL);
2824 if (hr != S_OK) return hr;
2825 TRACE("%s\n", debugstr_w(*value));
2826 return S_OK;
2828 case XmlNodeType_Whitespace:
2829 case XmlNodeType_Comment:
2830 break;
2832 default:
2833 FIXME("unexpected node type %d\n", type);
2834 return E_FAIL;
2838 return E_FAIL;
2841 static HRESULT read_variantbool_value(IXmlReader *reader, VARIANT_BOOL *vbool)
2843 static const WCHAR trueW[] = {'t','r','u','e',0};
2844 static const WCHAR falseW[] = {'f','a','l','s','e',0};
2845 HRESULT hr;
2846 WCHAR *value;
2848 hr = read_text_value(reader, &value);
2849 if (hr != S_OK) return hr;
2851 if (!lstrcmpW(value, trueW))
2852 *vbool = VARIANT_TRUE;
2853 else if (!lstrcmpW(value, falseW))
2854 *vbool = VARIANT_FALSE;
2855 else
2857 WARN("unexpected bool value %s\n", debugstr_w(value));
2858 return SCHED_E_INVALIDVALUE;
2861 return S_OK;
2864 static HRESULT read_int_value(IXmlReader *reader, int *int_val)
2866 HRESULT hr;
2867 WCHAR *value;
2869 hr = read_text_value(reader, &value);
2870 if (hr != S_OK) return hr;
2872 *int_val = strtolW(value, NULL, 10);
2874 return S_OK;
2877 static HRESULT read_triggers(IXmlReader *reader, ITaskDefinition *taskdef)
2879 FIXME("stub\n");
2880 return S_OK;
2883 static HRESULT read_principal_attributes(IXmlReader *reader, IPrincipal *principal)
2885 HRESULT hr;
2886 const WCHAR *name;
2887 const WCHAR *value;
2889 hr = IXmlReader_MoveToFirstAttribute(reader);
2891 while (hr == S_OK)
2893 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2894 if (hr != S_OK) break;
2896 hr = IXmlReader_GetValue(reader, &value, NULL);
2897 if (hr != S_OK) break;
2899 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
2901 if (!lstrcmpW(name, id))
2902 IPrincipal_put_Id(principal, (BSTR)value);
2903 else
2904 FIXME("unhandled Principal attribute %s\n", debugstr_w(name));
2906 hr = IXmlReader_MoveToNextAttribute(reader);
2909 return S_OK;
2912 static HRESULT read_principal(IXmlReader *reader, IPrincipal *principal)
2914 HRESULT hr;
2915 XmlNodeType type;
2916 const WCHAR *name;
2917 WCHAR *value;
2919 if (IXmlReader_IsEmptyElement(reader))
2921 TRACE("Principal is empty\n");
2922 return S_OK;
2925 read_principal_attributes(reader, principal);
2927 while (IXmlReader_Read(reader, &type) == S_OK)
2929 switch (type)
2931 case XmlNodeType_EndElement:
2932 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2933 if (hr != S_OK) return hr;
2935 TRACE("/%s\n", debugstr_w(name));
2937 if (!lstrcmpW(name, principalW))
2938 return S_OK;
2940 break;
2942 case XmlNodeType_Element:
2943 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2944 if (hr != S_OK) return hr;
2946 TRACE("Element: %s\n", debugstr_w(name));
2948 if (!lstrcmpW(name, UserId))
2950 hr = read_text_value(reader, &value);
2951 if (hr == S_OK)
2952 IPrincipal_put_UserId(principal, value);
2954 else if (!lstrcmpW(name, LogonType))
2956 hr = read_text_value(reader, &value);
2957 if (hr == S_OK)
2959 TASK_LOGON_TYPE logon = TASK_LOGON_NONE;
2961 if (!lstrcmpW(value, InteractiveToken))
2962 logon = TASK_LOGON_INTERACTIVE_TOKEN;
2963 else
2964 FIXME("unhandled LogonType %s\n", debugstr_w(value));
2966 IPrincipal_put_LogonType(principal, logon);
2969 else if (!lstrcmpW(name, RunLevel))
2971 hr = read_text_value(reader, &value);
2972 if (hr == S_OK)
2974 TASK_RUNLEVEL_TYPE level = TASK_RUNLEVEL_LUA;
2976 if (!lstrcmpW(value, LeastPrivilege))
2977 level = TASK_RUNLEVEL_LUA;
2978 else
2979 FIXME("unhandled RunLevel %s\n", debugstr_w(value));
2981 IPrincipal_put_RunLevel(principal, level);
2984 else
2985 FIXME("unhandled Principal element %s\n", debugstr_w(name));
2987 break;
2989 case XmlNodeType_Whitespace:
2990 case XmlNodeType_Comment:
2991 break;
2993 default:
2994 FIXME("unhandled Principal node type %d\n", type);
2995 break;
2999 WARN("Principal was not terminated\n");
3000 return E_FAIL;
3003 static HRESULT read_principals(IXmlReader *reader, ITaskDefinition *taskdef)
3005 HRESULT hr;
3006 XmlNodeType type;
3007 const WCHAR *name;
3009 if (IXmlReader_IsEmptyElement(reader))
3011 TRACE("Principals is empty\n");
3012 return S_OK;
3015 while (IXmlReader_Read(reader, &type) == S_OK)
3017 switch (type)
3019 case XmlNodeType_EndElement:
3020 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3021 if (hr != S_OK) return hr;
3023 TRACE("/%s\n", debugstr_w(name));
3025 if (!lstrcmpW(name, Principals))
3026 return S_OK;
3028 break;
3030 case XmlNodeType_Element:
3031 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3032 if (hr != S_OK) return hr;
3034 TRACE("Element: %s\n", debugstr_w(name));
3036 if (!lstrcmpW(name, principalW))
3038 IPrincipal *principal;
3040 hr = ITaskDefinition_get_Principal(taskdef, &principal);
3041 if (hr != S_OK) return hr;
3042 hr = read_principal(reader, principal);
3043 IPrincipal_Release(principal);
3045 else
3046 FIXME("unhandled Principals element %s\n", debugstr_w(name));
3048 break;
3050 case XmlNodeType_Whitespace:
3051 case XmlNodeType_Comment:
3052 break;
3054 default:
3055 FIXME("unhandled Principals node type %d\n", type);
3056 break;
3060 WARN("Principals was not terminated\n");
3061 return E_FAIL;
3064 static HRESULT read_actions(IXmlReader *reader, ITaskDefinition *taskdef)
3066 FIXME("stub\n");
3067 return S_OK;
3070 static HRESULT read_idle_settings(IXmlReader *reader, ITaskSettings *taskset)
3072 FIXME("stub\n");
3073 return S_OK;
3076 static HRESULT read_settings(IXmlReader *reader, ITaskSettings *taskset)
3078 HRESULT hr;
3079 XmlNodeType type;
3080 const WCHAR *name;
3081 WCHAR *value;
3082 VARIANT_BOOL bool_val;
3083 int int_val;
3085 if (IXmlReader_IsEmptyElement(reader))
3087 TRACE("Settings is empty\n");
3088 return S_OK;
3091 while (IXmlReader_Read(reader, &type) == S_OK)
3093 switch (type)
3095 case XmlNodeType_EndElement:
3096 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3097 if (hr != S_OK) return hr;
3099 TRACE("/%s\n", debugstr_w(name));
3101 if (!lstrcmpW(name, Settings))
3102 return S_OK;
3104 break;
3106 case XmlNodeType_Element:
3107 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3108 if (hr != S_OK) return hr;
3110 TRACE("Element: %s\n", debugstr_w(name));
3112 if (!lstrcmpW(name, MultipleInstancesPolicy))
3114 hr = read_text_value(reader, &value);
3115 if (hr == S_OK)
3117 int_val = TASK_INSTANCES_IGNORE_NEW;
3119 if (!lstrcmpW(value, IgnoreNew))
3120 int_val = TASK_INSTANCES_IGNORE_NEW;
3121 else
3122 FIXME("unhandled MultipleInstancesPolicy %s\n", debugstr_w(value));
3124 ITaskSettings_put_MultipleInstances(taskset, int_val);
3127 else if (!lstrcmpW(name, DisallowStartIfOnBatteries))
3129 hr = read_variantbool_value(reader, &bool_val);
3130 if (hr != S_OK) return hr;
3131 ITaskSettings_put_DisallowStartIfOnBatteries(taskset, bool_val);
3133 else if (!lstrcmpW(name, AllowStartOnDemand))
3135 hr = read_variantbool_value(reader, &bool_val);
3136 if (hr != S_OK) return hr;
3137 ITaskSettings_put_AllowDemandStart(taskset, bool_val);
3139 else if (!lstrcmpW(name, StopIfGoingOnBatteries))
3141 hr = read_variantbool_value(reader, &bool_val);
3142 if (hr != S_OK) return hr;
3143 ITaskSettings_put_StopIfGoingOnBatteries(taskset, bool_val);
3145 else if (!lstrcmpW(name, AllowHardTerminate))
3147 hr = read_variantbool_value(reader, &bool_val);
3148 if (hr != S_OK) return hr;
3149 ITaskSettings_put_AllowHardTerminate(taskset, bool_val);
3151 else if (!lstrcmpW(name, StartWhenAvailable))
3153 hr = read_variantbool_value(reader, &bool_val);
3154 if (hr != S_OK) return hr;
3155 ITaskSettings_put_StartWhenAvailable(taskset, bool_val);
3157 else if (!lstrcmpW(name, RunOnlyIfNetworkAvailable))
3159 hr = read_variantbool_value(reader, &bool_val);
3160 if (hr != S_OK) return hr;
3161 ITaskSettings_put_RunOnlyIfNetworkAvailable(taskset, bool_val);
3163 else if (!lstrcmpW(name, Enabled))
3165 hr = read_variantbool_value(reader, &bool_val);
3166 if (hr != S_OK) return hr;
3167 ITaskSettings_put_Enabled(taskset, bool_val);
3169 else if (!lstrcmpW(name, Hidden))
3171 hr = read_variantbool_value(reader, &bool_val);
3172 if (hr != S_OK) return hr;
3173 ITaskSettings_put_Hidden(taskset, bool_val);
3175 else if (!lstrcmpW(name, RunOnlyIfIdle))
3177 hr = read_variantbool_value(reader, &bool_val);
3178 if (hr != S_OK) return hr;
3179 ITaskSettings_put_RunOnlyIfIdle(taskset, bool_val);
3181 else if (!lstrcmpW(name, WakeToRun))
3183 hr = read_variantbool_value(reader, &bool_val);
3184 if (hr != S_OK) return hr;
3185 ITaskSettings_put_WakeToRun(taskset, bool_val);
3187 else if (!lstrcmpW(name, ExecutionTimeLimit))
3189 hr = read_text_value(reader, &value);
3190 if (hr == S_OK)
3191 ITaskSettings_put_ExecutionTimeLimit(taskset, value);
3193 else if (!lstrcmpW(name, Priority))
3195 hr = read_int_value(reader, &int_val);
3196 if (hr == S_OK)
3197 ITaskSettings_put_Priority(taskset, int_val);
3199 else if (!lstrcmpW(name, IdleSettings))
3201 hr = read_idle_settings(reader, taskset);
3202 if (hr != S_OK) return hr;
3204 else
3205 FIXME("unhandled Settings element %s\n", debugstr_w(name));
3207 break;
3209 case XmlNodeType_Whitespace:
3210 case XmlNodeType_Comment:
3211 break;
3213 default:
3214 FIXME("unhandled Settings node type %d\n", type);
3215 break;
3219 WARN("Settings was not terminated\n");
3220 return SCHED_E_MALFORMEDXML;
3223 static HRESULT read_registration_info(IXmlReader *reader, IRegistrationInfo *info)
3225 HRESULT hr;
3226 XmlNodeType type;
3227 const WCHAR *name;
3228 WCHAR *value;
3230 if (IXmlReader_IsEmptyElement(reader))
3232 TRACE("RegistrationInfo is empty\n");
3233 return S_OK;
3236 while (IXmlReader_Read(reader, &type) == S_OK)
3238 switch (type)
3240 case XmlNodeType_EndElement:
3241 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3242 if (hr != S_OK) return hr;
3244 TRACE("/%s\n", debugstr_w(name));
3246 if (!lstrcmpW(name, RegistrationInfo))
3247 return S_OK;
3249 break;
3251 case XmlNodeType_Element:
3252 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3253 if (hr != S_OK) return hr;
3255 TRACE("Element: %s\n", debugstr_w(name));
3257 if (!lstrcmpW(name, Author))
3259 hr = read_text_value(reader, &value);
3260 if (hr == S_OK)
3261 IRegistrationInfo_put_Author(info, value);
3263 else if (!lstrcmpW(name, Description))
3265 hr = read_text_value(reader, &value);
3266 if (hr == S_OK)
3267 IRegistrationInfo_put_Description(info, value);
3269 else
3270 FIXME("unhandled RegistrationInfo element %s\n", debugstr_w(name));
3272 break;
3274 case XmlNodeType_Whitespace:
3275 case XmlNodeType_Comment:
3276 break;
3278 default:
3279 FIXME("unhandled RegistrationInfo node type %d\n", type);
3280 break;
3284 WARN("RegistrationInfo was not terminated\n");
3285 return SCHED_E_MALFORMEDXML;
3288 static HRESULT read_task_attributes(IXmlReader *reader, ITaskDefinition *taskdef)
3290 HRESULT hr;
3291 ITaskSettings *taskset;
3292 const WCHAR *name;
3293 const WCHAR *value;
3294 BOOL xmlns_ok = FALSE;
3296 TRACE("\n");
3298 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3299 if (hr != S_OK) return hr;
3301 hr = IXmlReader_MoveToFirstAttribute(reader);
3303 while (hr == S_OK)
3305 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3306 if (hr != S_OK) break;
3308 hr = IXmlReader_GetValue(reader, &value, NULL);
3309 if (hr != S_OK) break;
3311 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
3313 if (!lstrcmpW(name, version))
3315 TASK_COMPATIBILITY compatibility = TASK_COMPATIBILITY_V2;
3317 if (!lstrcmpW(value, v1_0))
3318 compatibility = TASK_COMPATIBILITY_AT;
3319 else if (!lstrcmpW(value, v1_1))
3320 compatibility = TASK_COMPATIBILITY_V1;
3321 else if (!lstrcmpW(value, v1_2))
3322 compatibility = TASK_COMPATIBILITY_V2;
3323 else if (!lstrcmpW(value, v1_3))
3324 compatibility = TASK_COMPATIBILITY_V2_1;
3325 else
3326 FIXME("unknown version %s\n", debugstr_w(value));
3328 ITaskSettings_put_Compatibility(taskset, compatibility);
3330 else if (!lstrcmpW(name, xmlns))
3332 if (lstrcmpW(value, task_ns))
3334 FIXME("unknown namespace %s\n", debugstr_w(value));
3335 break;
3337 xmlns_ok = TRUE;
3339 else
3340 FIXME("unhandled Task attribute %s\n", debugstr_w(name));
3342 hr = IXmlReader_MoveToNextAttribute(reader);
3345 ITaskSettings_Release(taskset);
3346 return xmlns_ok ? S_OK : SCHED_E_NAMESPACE;
3349 static HRESULT read_task(IXmlReader *reader, ITaskDefinition *taskdef)
3351 HRESULT hr;
3352 XmlNodeType type;
3353 const WCHAR *name;
3355 if (IXmlReader_IsEmptyElement(reader))
3357 TRACE("Task is empty\n");
3358 return S_OK;
3361 while (IXmlReader_Read(reader, &type) == S_OK)
3363 switch (type)
3365 case XmlNodeType_EndElement:
3366 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3367 if (hr != S_OK) return hr;
3369 TRACE("/%s\n", debugstr_w(name));
3371 if (!lstrcmpW(name, Task))
3372 return S_OK;
3374 break;
3376 case XmlNodeType_Element:
3377 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3378 if (hr != S_OK) return hr;
3380 TRACE("Element: %s\n", debugstr_w(name));
3382 if (!lstrcmpW(name, RegistrationInfo))
3384 IRegistrationInfo *info;
3386 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &info);
3387 if (hr != S_OK) return hr;
3388 hr = read_registration_info(reader, info);
3389 IRegistrationInfo_Release(info);
3391 else if (!lstrcmpW(name, Settings))
3393 ITaskSettings *taskset;
3395 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3396 if (hr != S_OK) return hr;
3397 hr = read_settings(reader, taskset);
3398 ITaskSettings_Release(taskset);
3400 else if (!lstrcmpW(name, Triggers))
3401 hr = read_triggers(reader, taskdef);
3402 else if (!lstrcmpW(name, Principals))
3403 hr = read_principals(reader, taskdef);
3404 else if (!lstrcmpW(name, actionsW))
3405 hr = read_actions(reader, taskdef);
3406 else
3407 FIXME("unhandled Task element %s\n", debugstr_w(name));
3409 if (hr != S_OK) return hr;
3410 break;
3412 case XmlNodeType_Comment:
3413 case XmlNodeType_Whitespace:
3414 break;
3416 default:
3417 FIXME("unhandled Task node type %d\n", type);
3418 break;
3422 WARN("Task was not terminated\n");
3423 return SCHED_E_MALFORMEDXML;
3426 static HRESULT read_xml(IXmlReader *reader, ITaskDefinition *taskdef)
3428 HRESULT hr;
3429 XmlNodeType type;
3430 const WCHAR *name;
3432 while (IXmlReader_Read(reader, &type) == S_OK)
3434 switch (type)
3436 case XmlNodeType_XmlDeclaration:
3437 TRACE("XmlDeclaration\n");
3438 break;
3440 case XmlNodeType_Element:
3441 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3442 if (hr != S_OK) return hr;
3444 TRACE("Element: %s\n", debugstr_w(name));
3446 if (!lstrcmpW(name, Task))
3448 hr = read_task_attributes(reader, taskdef);
3449 if (hr != S_OK) return hr;
3451 return read_task(reader, taskdef);
3453 else
3454 FIXME("unhandled XML element %s\n", debugstr_w(name));
3456 break;
3458 case XmlNodeType_Comment:
3459 case XmlNodeType_Whitespace:
3460 break;
3462 default:
3463 FIXME("unhandled XML node type %d\n", type);
3464 break;
3468 WARN("Task definition was not found\n");
3469 return SCHED_E_MALFORMEDXML;
3472 static HRESULT WINAPI TaskDefinition_put_XmlText(ITaskDefinition *iface, BSTR xml)
3474 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
3475 HRESULT hr;
3476 IStream *stream;
3477 IXmlReader *reader;
3478 HGLOBAL hmem;
3479 void *buf;
3481 TRACE("%p,%s\n", iface, debugstr_w(xml));
3483 if (!xml) return E_INVALIDARG;
3485 hmem = GlobalAlloc(0, lstrlenW(xml) * sizeof(WCHAR));
3486 if (!hmem) return E_OUTOFMEMORY;
3488 buf = GlobalLock(hmem);
3489 memcpy(buf, xml, lstrlenW(xml) * sizeof(WCHAR));
3490 GlobalUnlock(hmem);
3492 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
3493 if (hr != S_OK)
3495 GlobalFree(hmem);
3496 return hr;
3499 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
3500 if (hr != S_OK)
3502 IStream_Release(stream);
3503 return hr;
3506 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
3507 if (hr == S_OK)
3509 if (taskdef->reginfo)
3511 IRegistrationInfo_Release(taskdef->reginfo);
3512 taskdef->reginfo = NULL;
3514 if (taskdef->taskset)
3516 ITaskSettings_Release(taskdef->taskset);
3517 taskdef->taskset = NULL;
3519 if (taskdef->triggers)
3521 ITriggerCollection_Release(taskdef->triggers);
3522 taskdef->triggers = NULL;
3524 if (taskdef->principal)
3526 IPrincipal_Release(taskdef->principal);
3527 taskdef->principal = NULL;
3529 if (taskdef->actions)
3531 IActionCollection_Release(taskdef->actions);
3532 taskdef->actions = NULL;
3535 hr = read_xml(reader, iface);
3538 IXmlReader_Release(reader);
3539 IStream_Release(stream);
3541 return hr;
3544 static const ITaskDefinitionVtbl TaskDefinition_vtbl =
3546 TaskDefinition_QueryInterface,
3547 TaskDefinition_AddRef,
3548 TaskDefinition_Release,
3549 TaskDefinition_GetTypeInfoCount,
3550 TaskDefinition_GetTypeInfo,
3551 TaskDefinition_GetIDsOfNames,
3552 TaskDefinition_Invoke,
3553 TaskDefinition_get_RegistrationInfo,
3554 TaskDefinition_put_RegistrationInfo,
3555 TaskDefinition_get_Triggers,
3556 TaskDefinition_put_Triggers,
3557 TaskDefinition_get_Settings,
3558 TaskDefinition_put_Settings,
3559 TaskDefinition_get_Data,
3560 TaskDefinition_put_Data,
3561 TaskDefinition_get_Principal,
3562 TaskDefinition_put_Principal,
3563 TaskDefinition_get_Actions,
3564 TaskDefinition_put_Actions,
3565 TaskDefinition_get_XmlText,
3566 TaskDefinition_put_XmlText
3569 HRESULT TaskDefinition_create(ITaskDefinition **obj)
3571 TaskDefinition *taskdef;
3573 taskdef = heap_alloc_zero(sizeof(*taskdef));
3574 if (!taskdef) return E_OUTOFMEMORY;
3576 taskdef->ITaskDefinition_iface.lpVtbl = &TaskDefinition_vtbl;
3577 taskdef->ref = 1;
3578 *obj = &taskdef->ITaskDefinition_iface;
3580 TRACE("created %p\n", *obj);
3582 return S_OK;
3585 typedef struct
3587 ITaskService ITaskService_iface;
3588 LONG ref;
3589 BOOL connected;
3590 DWORD version;
3591 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3592 } TaskService;
3594 static inline TaskService *impl_from_ITaskService(ITaskService *iface)
3596 return CONTAINING_RECORD(iface, TaskService, ITaskService_iface);
3599 static ULONG WINAPI TaskService_AddRef(ITaskService *iface)
3601 TaskService *task_svc = impl_from_ITaskService(iface);
3602 return InterlockedIncrement(&task_svc->ref);
3605 static ULONG WINAPI TaskService_Release(ITaskService *iface)
3607 TaskService *task_svc = impl_from_ITaskService(iface);
3608 LONG ref = InterlockedDecrement(&task_svc->ref);
3610 if (!ref)
3612 TRACE("destroying %p\n", iface);
3613 heap_free(task_svc);
3616 return ref;
3619 static HRESULT WINAPI TaskService_QueryInterface(ITaskService *iface, REFIID riid, void **obj)
3621 if (!riid || !obj) return E_INVALIDARG;
3623 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
3625 if (IsEqualGUID(riid, &IID_ITaskService) ||
3626 IsEqualGUID(riid, &IID_IDispatch) ||
3627 IsEqualGUID(riid, &IID_IUnknown))
3629 ITaskService_AddRef(iface);
3630 *obj = iface;
3631 return S_OK;
3634 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
3635 *obj = NULL;
3636 return E_NOINTERFACE;
3639 static HRESULT WINAPI TaskService_GetTypeInfoCount(ITaskService *iface, UINT *count)
3641 FIXME("%p,%p: stub\n", iface, count);
3642 return E_NOTIMPL;
3645 static HRESULT WINAPI TaskService_GetTypeInfo(ITaskService *iface, UINT index, LCID lcid, ITypeInfo **info)
3647 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
3648 return E_NOTIMPL;
3651 static HRESULT WINAPI TaskService_GetIDsOfNames(ITaskService *iface, REFIID riid, LPOLESTR *names,
3652 UINT count, LCID lcid, DISPID *dispid)
3654 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
3655 return E_NOTIMPL;
3658 static HRESULT WINAPI TaskService_Invoke(ITaskService *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
3659 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
3661 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
3662 params, result, excepinfo, argerr);
3663 return E_NOTIMPL;
3666 static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITaskFolder **folder)
3668 TaskService *task_svc = impl_from_ITaskService(iface);
3670 TRACE("%p,%s,%p\n", iface, debugstr_w(path), folder);
3672 if (!folder) return E_POINTER;
3674 if (!task_svc->connected)
3675 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3677 return TaskFolder_create(path, NULL, folder, FALSE);
3680 static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks)
3682 FIXME("%p,%x,%p: stub\n", iface, flags, tasks);
3683 return E_NOTIMPL;
3686 static HRESULT WINAPI TaskService_NewTask(ITaskService *iface, DWORD flags, ITaskDefinition **definition)
3688 TRACE("%p,%x,%p\n", iface, flags, definition);
3690 if (!definition) return E_POINTER;
3692 if (flags)
3693 FIXME("unsupported flags %x\n", flags);
3695 return TaskDefinition_create(definition);
3698 static inline BOOL is_variant_null(const VARIANT *var)
3700 return V_VT(var) == VT_EMPTY || V_VT(var) == VT_NULL ||
3701 (V_VT(var) == VT_BSTR && (V_BSTR(var) == NULL || !*V_BSTR(var)));
3704 static HRESULT start_schedsvc(void)
3706 static const WCHAR scheduleW[] = { 'S','c','h','e','d','u','l','e',0 };
3707 SC_HANDLE scm, service;
3708 SERVICE_STATUS_PROCESS status;
3709 ULONGLONG start_time;
3710 HRESULT hr = SCHED_E_SERVICE_NOT_RUNNING;
3712 TRACE("Trying to start %s service\n", debugstr_w(scheduleW));
3714 scm = OpenSCManagerW(NULL, NULL, 0);
3715 if (!scm) return SCHED_E_SERVICE_NOT_INSTALLED;
3717 service = OpenServiceW(scm, scheduleW, SERVICE_START | SERVICE_QUERY_STATUS);
3718 if (service)
3720 if (StartServiceW(service, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
3722 start_time = GetTickCount64();
3725 DWORD dummy;
3727 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(status), &dummy))
3729 WARN("failed to query scheduler status (%u)\n", GetLastError());
3730 break;
3733 if (status.dwCurrentState == SERVICE_RUNNING)
3735 hr = S_OK;
3736 break;
3739 if (GetTickCount64() - start_time > 30000) break;
3740 Sleep(1000);
3742 } while (status.dwCurrentState == SERVICE_START_PENDING);
3744 if (status.dwCurrentState != SERVICE_RUNNING)
3745 WARN("scheduler failed to start %u\n", status.dwCurrentState);
3747 else
3748 WARN("failed to start scheduler service (%u)\n", GetLastError());
3750 CloseServiceHandle(service);
3752 else
3753 WARN("failed to open scheduler service (%u)\n", GetLastError());
3755 CloseServiceHandle(scm);
3756 return hr;
3759 static HRESULT WINAPI TaskService_Connect(ITaskService *iface, VARIANT server, VARIANT user, VARIANT domain, VARIANT password)
3761 static WCHAR ncalrpc[] = { 'n','c','a','l','r','p','c',0 };
3762 TaskService *task_svc = impl_from_ITaskService(iface);
3763 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3764 DWORD len;
3765 HRESULT hr;
3766 RPC_WSTR binding_str;
3767 extern handle_t rpc_handle;
3769 TRACE("%p,%s,%s,%s,%s\n", iface, debugstr_variant(&server), debugstr_variant(&user),
3770 debugstr_variant(&domain), debugstr_variant(&password));
3772 if (!is_variant_null(&user) || !is_variant_null(&domain) || !is_variant_null(&password))
3773 FIXME("user/domain/password are ignored\n");
3775 len = sizeof(comp_name)/sizeof(comp_name[0]);
3776 if (!GetComputerNameW(comp_name, &len))
3777 return HRESULT_FROM_WIN32(GetLastError());
3779 if (!is_variant_null(&server))
3781 const WCHAR *server_name;
3783 if (V_VT(&server) != VT_BSTR)
3785 FIXME("server variant type %d is not supported\n", V_VT(&server));
3786 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3789 /* skip UNC prefix if any */
3790 server_name = V_BSTR(&server);
3791 if (server_name[0] == '\\' && server_name[1] == '\\')
3792 server_name += 2;
3794 if (strcmpiW(server_name, comp_name))
3796 FIXME("connection to remote server %s is not supported\n", debugstr_w(V_BSTR(&server)));
3797 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3801 hr = start_schedsvc();
3802 if (hr != S_OK) return hr;
3804 hr = RpcStringBindingComposeW(NULL, ncalrpc, NULL, NULL, NULL, &binding_str);
3805 if (hr != RPC_S_OK) return hr;
3806 hr = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
3807 RpcStringFreeW(&binding_str);
3808 if (hr != RPC_S_OK) return hr;
3810 /* Make sure that the connection works */
3811 hr = SchRpcHighestVersion(&task_svc->version);
3812 if (hr != S_OK) return hr;
3814 TRACE("server version %#x\n", task_svc->version);
3816 strcpyW(task_svc->comp_name, comp_name);
3817 task_svc->connected = TRUE;
3819 return S_OK;
3822 static HRESULT WINAPI TaskService_get_Connected(ITaskService *iface, VARIANT_BOOL *connected)
3824 TaskService *task_svc = impl_from_ITaskService(iface);
3826 TRACE("%p,%p\n", iface, connected);
3828 if (!connected) return E_POINTER;
3830 *connected = task_svc->connected ? VARIANT_TRUE : VARIANT_FALSE;
3832 return S_OK;
3835 static HRESULT WINAPI TaskService_get_TargetServer(ITaskService *iface, BSTR *server)
3837 TaskService *task_svc = impl_from_ITaskService(iface);
3839 TRACE("%p,%p\n", iface, server);
3841 if (!server) return E_POINTER;
3843 if (!task_svc->connected)
3844 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3846 *server = SysAllocString(task_svc->comp_name);
3847 if (!*server) return E_OUTOFMEMORY;
3849 return S_OK;
3852 static HRESULT WINAPI TaskService_get_ConnectedUser(ITaskService *iface, BSTR *user)
3854 FIXME("%p,%p: stub\n", iface, user);
3855 return E_NOTIMPL;
3858 static HRESULT WINAPI TaskService_get_ConnectedDomain(ITaskService *iface, BSTR *domain)
3860 FIXME("%p,%p: stub\n", iface, domain);
3861 return E_NOTIMPL;
3864 static HRESULT WINAPI TaskService_get_HighestVersion(ITaskService *iface, DWORD *version)
3866 TaskService *task_svc = impl_from_ITaskService(iface);
3868 TRACE("%p,%p\n", iface, version);
3870 if (!version) return E_POINTER;
3872 if (!task_svc->connected)
3873 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3875 *version = task_svc->version;
3877 return S_OK;
3880 static const ITaskServiceVtbl TaskService_vtbl =
3882 TaskService_QueryInterface,
3883 TaskService_AddRef,
3884 TaskService_Release,
3885 TaskService_GetTypeInfoCount,
3886 TaskService_GetTypeInfo,
3887 TaskService_GetIDsOfNames,
3888 TaskService_Invoke,
3889 TaskService_GetFolder,
3890 TaskService_GetRunningTasks,
3891 TaskService_NewTask,
3892 TaskService_Connect,
3893 TaskService_get_Connected,
3894 TaskService_get_TargetServer,
3895 TaskService_get_ConnectedUser,
3896 TaskService_get_ConnectedDomain,
3897 TaskService_get_HighestVersion
3900 HRESULT TaskService_create(void **obj)
3902 TaskService *task_svc;
3904 task_svc = heap_alloc(sizeof(*task_svc));
3905 if (!task_svc) return E_OUTOFMEMORY;
3907 task_svc->ITaskService_iface.lpVtbl = &TaskService_vtbl;
3908 task_svc->ref = 1;
3909 task_svc->connected = FALSE;
3910 *obj = &task_svc->ITaskService_iface;
3912 TRACE("created %p\n", *obj);
3914 return S_OK;
3917 void __RPC_FAR *__RPC_USER MIDL_user_allocate(SIZE_T n)
3919 return HeapAlloc(GetProcessHeap(), 0, n);
3922 void __RPC_USER MIDL_user_free(void __RPC_FAR *p)
3924 HeapFree(GetProcessHeap(), 0, p);