advapi32/tests: Allow ERROR_ACCESS_DENIED for newer Win10.
[wine.git] / dlls / taskschd / task.c
blob1306c8c8f9159dbd43efb719cea6c257368d3446
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);
584 WCHAR *str = NULL;
586 TRACE("%p,%s\n", iface, debugstr_w(description));
588 if (description && !(str = heap_strdupW(description))) return E_OUTOFMEMORY;
589 heap_free(reginfo->description);
590 reginfo->description = str;
591 return S_OK;
594 static HRESULT WINAPI RegistrationInfo_get_Author(IRegistrationInfo *iface, BSTR *author)
596 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
598 TRACE("%p,%p\n", iface, author);
600 if (!author) return E_POINTER;
602 if (!reginfo->author) *author = NULL;
603 else if (!(*author = SysAllocString(reginfo->author))) return E_OUTOFMEMORY;
605 return S_OK;
608 static HRESULT WINAPI RegistrationInfo_put_Author(IRegistrationInfo *iface, BSTR author)
610 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
611 WCHAR *str = NULL;
613 TRACE("%p,%s\n", iface, debugstr_w(author));
615 if (author && !(str = heap_strdupW(author))) return E_OUTOFMEMORY;
616 heap_free(reginfo->author);
617 reginfo->author = str;
618 return S_OK;
621 static HRESULT WINAPI RegistrationInfo_get_Version(IRegistrationInfo *iface, BSTR *version)
623 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
625 TRACE("%p,%p\n", iface, version);
627 if (!version) return E_POINTER;
629 if (!reginfo->version) *version = NULL;
630 else if (!(*version = SysAllocString(reginfo->version))) return E_OUTOFMEMORY;
632 return S_OK;
635 static HRESULT WINAPI RegistrationInfo_put_Version(IRegistrationInfo *iface, BSTR version)
637 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
638 WCHAR *str = NULL;
640 TRACE("%p,%s\n", iface, debugstr_w(version));
642 if (version && !(str = heap_strdupW(version))) return E_OUTOFMEMORY;
643 heap_free(reginfo->version);
644 reginfo->version = str;
645 return S_OK;
648 static HRESULT WINAPI RegistrationInfo_get_Date(IRegistrationInfo *iface, BSTR *date)
650 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
652 TRACE("%p,%p\n", iface, date);
654 if (!date) return E_POINTER;
656 if (!reginfo->date) *date = NULL;
657 else if (!(*date = SysAllocString(reginfo->date))) return E_OUTOFMEMORY;
659 return S_OK;
662 static HRESULT WINAPI RegistrationInfo_put_Date(IRegistrationInfo *iface, BSTR date)
664 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
665 WCHAR *str = NULL;
667 TRACE("%p,%s\n", iface, debugstr_w(date));
669 if (date && !(str = heap_strdupW(date))) return E_OUTOFMEMORY;
670 heap_free(reginfo->date);
671 reginfo->date = str;
672 return S_OK;
675 static HRESULT WINAPI RegistrationInfo_get_Documentation(IRegistrationInfo *iface, BSTR *doc)
677 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
679 TRACE("%p,%p\n", iface, doc);
681 if (!doc) return E_POINTER;
683 if (!reginfo->documentation) *doc = NULL;
684 else if (!(*doc = SysAllocString(reginfo->documentation))) return E_OUTOFMEMORY;
686 return S_OK;
689 static HRESULT WINAPI RegistrationInfo_put_Documentation(IRegistrationInfo *iface, BSTR doc)
691 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
692 WCHAR *str = NULL;
694 TRACE("%p,%s\n", iface, debugstr_w(doc));
696 if (doc && !(str = heap_strdupW(doc))) return E_OUTOFMEMORY;
697 heap_free(reginfo->documentation);
698 reginfo->documentation = str;
699 return S_OK;
702 static HRESULT WINAPI RegistrationInfo_get_XmlText(IRegistrationInfo *iface, BSTR *xml)
704 FIXME("%p,%p: stub\n", iface, xml);
705 return E_NOTIMPL;
708 static HRESULT WINAPI RegistrationInfo_put_XmlText(IRegistrationInfo *iface, BSTR xml)
710 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
711 return E_NOTIMPL;
714 static HRESULT WINAPI RegistrationInfo_get_URI(IRegistrationInfo *iface, BSTR *uri)
716 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
718 TRACE("%p,%p\n", iface, uri);
720 if (!uri) return E_POINTER;
722 if (!reginfo->uri) *uri = NULL;
723 else if (!(*uri = SysAllocString(reginfo->uri))) return E_OUTOFMEMORY;
725 return S_OK;
728 static HRESULT WINAPI RegistrationInfo_put_URI(IRegistrationInfo *iface, BSTR uri)
730 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
731 WCHAR *str = NULL;
733 TRACE("%p,%s\n", iface, debugstr_w(uri));
735 if (uri && !(str = heap_strdupW(uri))) return E_OUTOFMEMORY;
736 heap_free(reginfo->uri);
737 reginfo->uri = str;
738 return S_OK;
741 static HRESULT WINAPI RegistrationInfo_get_SecurityDescriptor(IRegistrationInfo *iface, VARIANT *sddl)
743 FIXME("%p,%p: stub\n", iface, sddl);
744 return E_NOTIMPL;
747 static HRESULT WINAPI RegistrationInfo_put_SecurityDescriptor(IRegistrationInfo *iface, VARIANT sddl)
749 FIXME("%p,%s: stub\n", iface, debugstr_variant(&sddl));
750 return S_OK;
753 static HRESULT WINAPI RegistrationInfo_get_Source(IRegistrationInfo *iface, BSTR *source)
755 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
757 TRACE("%p,%p\n", iface, source);
759 if (!source) return E_POINTER;
761 if (!reginfo->source) *source = NULL;
762 else if (!(*source = SysAllocString(reginfo->source))) return E_OUTOFMEMORY;
764 return S_OK;
767 static HRESULT WINAPI RegistrationInfo_put_Source(IRegistrationInfo *iface, BSTR source)
769 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
770 WCHAR *str = NULL;
772 TRACE("%p,%s\n", iface, debugstr_w(source));
774 if (source && !(str = heap_strdupW(source))) return E_OUTOFMEMORY;
775 heap_free(reginfo->source);
776 reginfo->source = str;
777 return S_OK;
780 static const IRegistrationInfoVtbl RegistrationInfo_vtbl =
782 RegistrationInfo_QueryInterface,
783 RegistrationInfo_AddRef,
784 RegistrationInfo_Release,
785 RegistrationInfo_GetTypeInfoCount,
786 RegistrationInfo_GetTypeInfo,
787 RegistrationInfo_GetIDsOfNames,
788 RegistrationInfo_Invoke,
789 RegistrationInfo_get_Description,
790 RegistrationInfo_put_Description,
791 RegistrationInfo_get_Author,
792 RegistrationInfo_put_Author,
793 RegistrationInfo_get_Version,
794 RegistrationInfo_put_Version,
795 RegistrationInfo_get_Date,
796 RegistrationInfo_put_Date,
797 RegistrationInfo_get_Documentation,
798 RegistrationInfo_put_Documentation,
799 RegistrationInfo_get_XmlText,
800 RegistrationInfo_put_XmlText,
801 RegistrationInfo_get_URI,
802 RegistrationInfo_put_URI,
803 RegistrationInfo_get_SecurityDescriptor,
804 RegistrationInfo_put_SecurityDescriptor,
805 RegistrationInfo_get_Source,
806 RegistrationInfo_put_Source
809 static HRESULT RegistrationInfo_create(IRegistrationInfo **obj)
811 registration_info *reginfo;
813 reginfo = heap_alloc_zero(sizeof(*reginfo));
814 if (!reginfo) return E_OUTOFMEMORY;
816 reginfo->IRegistrationInfo_iface.lpVtbl = &RegistrationInfo_vtbl;
817 reginfo->ref = 1;
818 *obj = &reginfo->IRegistrationInfo_iface;
820 TRACE("created %p\n", *obj);
822 return S_OK;
825 typedef struct
827 ITaskSettings ITaskSettings_iface;
828 LONG ref;
829 WCHAR *restart_interval;
830 WCHAR *execution_time_limit;
831 WCHAR *delete_expired_task_after;
832 int restart_count;
833 int priority;
834 TASK_INSTANCES_POLICY policy;
835 TASK_COMPATIBILITY compatibility;
836 BOOL allow_on_demand_start;
837 BOOL stop_if_going_on_batteries;
838 BOOL disallow_start_if_on_batteries;
839 BOOL allow_hard_terminate;
840 BOOL start_when_available;
841 BOOL run_only_if_network_available;
842 BOOL enabled;
843 BOOL hidden;
844 BOOL run_only_if_idle;
845 BOOL wake_to_run;
846 } TaskSettings;
848 static inline TaskSettings *impl_from_ITaskSettings(ITaskSettings *iface)
850 return CONTAINING_RECORD(iface, TaskSettings, ITaskSettings_iface);
853 static ULONG WINAPI TaskSettings_AddRef(ITaskSettings *iface)
855 TaskSettings *taskset = impl_from_ITaskSettings(iface);
856 return InterlockedIncrement(&taskset->ref);
859 static ULONG WINAPI TaskSettings_Release(ITaskSettings *iface)
861 TaskSettings *taskset = impl_from_ITaskSettings(iface);
862 LONG ref = InterlockedDecrement(&taskset->ref);
864 if (!ref)
866 TRACE("destroying %p\n", iface);
867 heap_free(taskset->restart_interval);
868 heap_free(taskset->execution_time_limit);
869 heap_free(taskset->delete_expired_task_after);
870 heap_free(taskset);
873 return ref;
876 static HRESULT WINAPI TaskSettings_QueryInterface(ITaskSettings *iface, REFIID riid, void **obj)
878 if (!riid || !obj) return E_INVALIDARG;
880 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
882 if (IsEqualGUID(riid, &IID_ITaskSettings) ||
883 IsEqualGUID(riid, &IID_IDispatch) ||
884 IsEqualGUID(riid, &IID_IUnknown))
886 ITaskSettings_AddRef(iface);
887 *obj = iface;
888 return S_OK;
891 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
892 *obj = NULL;
893 return E_NOINTERFACE;
896 static HRESULT WINAPI TaskSettings_GetTypeInfoCount(ITaskSettings *iface, UINT *count)
898 FIXME("%p,%p: stub\n", iface, count);
899 return E_NOTIMPL;
902 static HRESULT WINAPI TaskSettings_GetTypeInfo(ITaskSettings *iface, UINT index, LCID lcid, ITypeInfo **info)
904 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
905 return E_NOTIMPL;
908 static HRESULT WINAPI TaskSettings_GetIDsOfNames(ITaskSettings *iface, REFIID riid, LPOLESTR *names,
909 UINT count, LCID lcid, DISPID *dispid)
911 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
912 return E_NOTIMPL;
915 static HRESULT WINAPI TaskSettings_Invoke(ITaskSettings *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
916 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
918 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
919 params, result, excepinfo, argerr);
920 return E_NOTIMPL;
923 static HRESULT WINAPI TaskSettings_get_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL *allow)
925 TaskSettings *taskset = impl_from_ITaskSettings(iface);
927 TRACE("%p,%p\n", iface, allow);
929 if (!allow) return E_POINTER;
931 *allow = taskset->allow_on_demand_start ? VARIANT_TRUE : VARIANT_FALSE;
933 return S_OK;
936 static HRESULT WINAPI TaskSettings_put_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL allow)
938 TaskSettings *taskset = impl_from_ITaskSettings(iface);
940 TRACE("%p,%d\n", iface, allow);
942 taskset->allow_on_demand_start = allow ? TRUE : FALSE;
944 return S_OK;
947 static HRESULT WINAPI TaskSettings_get_RestartInterval(ITaskSettings *iface, BSTR *interval)
949 TaskSettings *taskset = impl_from_ITaskSettings(iface);
951 TRACE("%p,%p\n", iface, interval);
953 if (!interval) return E_POINTER;
955 if (!taskset->restart_interval)
957 *interval = NULL;
958 return S_OK;
961 if (!taskset->restart_interval) *interval = NULL;
962 else if (!(*interval = SysAllocString(taskset->restart_interval))) return E_OUTOFMEMORY;
964 return S_OK;
967 static HRESULT WINAPI TaskSettings_put_RestartInterval(ITaskSettings *iface, BSTR interval)
969 TaskSettings *taskset = impl_from_ITaskSettings(iface);
970 WCHAR *str = NULL;
972 TRACE("%p,%s\n", iface, debugstr_w(interval));
974 if (interval && !(str = heap_strdupW(interval))) return E_OUTOFMEMORY;
975 heap_free(taskset->restart_interval);
976 taskset->restart_interval = str;
978 return S_OK;
981 static HRESULT WINAPI TaskSettings_get_RestartCount(ITaskSettings *iface, INT *count)
983 TaskSettings *taskset = impl_from_ITaskSettings(iface);
985 TRACE("%p,%p\n", iface, count);
987 if (!count) return E_POINTER;
989 *count = taskset->restart_count;
991 return S_OK;
994 static HRESULT WINAPI TaskSettings_put_RestartCount(ITaskSettings *iface, INT count)
996 TaskSettings *taskset = impl_from_ITaskSettings(iface);
998 TRACE("%p,%d\n", iface, count);
1000 taskset->restart_count = count;
1002 return S_OK;
1005 static HRESULT WINAPI TaskSettings_get_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY *policy)
1007 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1009 TRACE("%p,%p\n", iface, policy);
1011 if (!policy) return E_POINTER;
1013 *policy = taskset->policy;
1015 return S_OK;
1018 static HRESULT WINAPI TaskSettings_put_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY policy)
1020 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1022 TRACE("%p,%d\n", iface, policy);
1024 taskset->policy = policy;
1026 return S_OK;
1029 static HRESULT WINAPI TaskSettings_get_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL *stop)
1031 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1033 TRACE("%p,%p\n", iface, stop);
1035 if (!stop) return E_POINTER;
1037 *stop = taskset->stop_if_going_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1039 return S_OK;
1042 static HRESULT WINAPI TaskSettings_put_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL stop)
1044 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1046 TRACE("%p,%d\n", iface, stop);
1048 taskset->stop_if_going_on_batteries = stop ? TRUE : FALSE;
1050 return S_OK;
1053 static HRESULT WINAPI TaskSettings_get_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL *disallow)
1055 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1057 TRACE("%p,%p\n", iface, disallow);
1059 if (!disallow) return E_POINTER;
1061 *disallow = taskset->disallow_start_if_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1063 return S_OK;
1066 static HRESULT WINAPI TaskSettings_put_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL disallow)
1068 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1070 TRACE("%p,%d\n", iface, disallow);
1072 taskset->disallow_start_if_on_batteries = disallow ? TRUE : FALSE;
1074 return S_OK;
1077 static HRESULT WINAPI TaskSettings_get_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL *allow)
1079 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1081 TRACE("%p,%p\n", iface, allow);
1083 if (!allow) return E_POINTER;
1085 *allow = taskset->allow_hard_terminate ? VARIANT_TRUE : VARIANT_FALSE;
1087 return S_OK;
1090 static HRESULT WINAPI TaskSettings_put_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL allow)
1092 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1094 TRACE("%p,%d\n", iface, allow);
1096 taskset->allow_hard_terminate = allow ? TRUE : FALSE;
1098 return S_OK;
1101 static HRESULT WINAPI TaskSettings_get_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL *start)
1103 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1105 TRACE("%p,%p\n", iface, start);
1107 if (!start) return E_POINTER;
1109 *start = taskset->start_when_available ? VARIANT_TRUE : VARIANT_FALSE;
1111 return S_OK;
1114 static HRESULT WINAPI TaskSettings_put_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL start)
1116 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1118 TRACE("%p,%d\n", iface, start);
1120 taskset->start_when_available = start ? TRUE : FALSE;
1122 return S_OK;
1125 static HRESULT WINAPI TaskSettings_get_XmlText(ITaskSettings *iface, BSTR *xml)
1127 FIXME("%p,%p: stub\n", iface, xml);
1128 return E_NOTIMPL;
1131 static HRESULT WINAPI TaskSettings_put_XmlText(ITaskSettings *iface, BSTR xml)
1133 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
1134 return E_NOTIMPL;
1137 static HRESULT WINAPI TaskSettings_get_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL *run)
1139 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1141 TRACE("%p,%p\n", iface, run);
1143 if (!run) return E_POINTER;
1145 *run = taskset->run_only_if_network_available ? VARIANT_TRUE : VARIANT_FALSE;
1147 return S_OK;
1150 static HRESULT WINAPI TaskSettings_put_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL run)
1152 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1154 TRACE("%p,%d\n", iface, run);
1156 taskset->run_only_if_network_available = run ? TRUE : FALSE;
1158 return S_OK;
1161 static HRESULT WINAPI TaskSettings_get_ExecutionTimeLimit(ITaskSettings *iface, BSTR *limit)
1163 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1165 TRACE("%p,%p\n", iface, limit);
1167 if (!limit) return E_POINTER;
1169 if (!taskset->execution_time_limit)
1171 *limit = NULL;
1172 return S_OK;
1175 if (!taskset->execution_time_limit) *limit = NULL;
1176 else if (!(*limit = SysAllocString(taskset->execution_time_limit))) return E_OUTOFMEMORY;
1178 return S_OK;
1181 static HRESULT WINAPI TaskSettings_put_ExecutionTimeLimit(ITaskSettings *iface, BSTR limit)
1183 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1184 WCHAR *str = NULL;
1186 TRACE("%p,%s\n", iface, debugstr_w(limit));
1188 if (limit && !(str = heap_strdupW(limit))) return E_OUTOFMEMORY;
1189 heap_free(taskset->execution_time_limit);
1190 taskset->execution_time_limit = str;
1192 return S_OK;
1195 static HRESULT WINAPI TaskSettings_get_Enabled(ITaskSettings *iface, VARIANT_BOOL *enabled)
1197 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1199 TRACE("%p,%p\n", iface, enabled);
1201 if (!enabled) return E_POINTER;
1203 *enabled = taskset->enabled ? VARIANT_TRUE : VARIANT_FALSE;
1205 return S_OK;
1208 static HRESULT WINAPI TaskSettings_put_Enabled(ITaskSettings *iface, VARIANT_BOOL enabled)
1210 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1212 TRACE("%p,%d\n", iface, enabled);
1214 taskset->enabled = enabled ? TRUE : FALSE;
1216 return S_OK;
1219 static HRESULT WINAPI TaskSettings_get_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR *delay)
1221 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1223 TRACE("%p,%p\n", iface, delay);
1225 if (!delay) return E_POINTER;
1227 if (!taskset->delete_expired_task_after) *delay = NULL;
1228 else if (!(*delay = SysAllocString(taskset->delete_expired_task_after))) return E_OUTOFMEMORY;
1230 return S_OK;
1233 static HRESULT WINAPI TaskSettings_put_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR delay)
1235 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1236 WCHAR *str = NULL;
1238 TRACE("%p,%s\n", iface, debugstr_w(delay));
1240 if (delay && !(str = heap_strdupW(delay))) return E_OUTOFMEMORY;
1241 heap_free(taskset->delete_expired_task_after);
1242 taskset->delete_expired_task_after = str;
1244 return S_OK;
1247 static HRESULT WINAPI TaskSettings_get_Priority(ITaskSettings *iface, INT *priority)
1249 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1251 TRACE("%p,%p\n", iface, priority);
1253 if (!priority) return E_POINTER;
1255 *priority = taskset->priority;
1257 return S_OK;
1260 static HRESULT WINAPI TaskSettings_put_Priority(ITaskSettings *iface, INT priority)
1262 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1264 TRACE("%p,%d\n", iface, priority);
1266 taskset->priority = priority;
1268 return S_OK;
1271 static HRESULT WINAPI TaskSettings_get_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY *level)
1273 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1275 TRACE("%p,%p\n", iface, level);
1277 if (!level) return E_POINTER;
1279 *level = taskset->compatibility;
1281 return S_OK;
1284 static HRESULT WINAPI TaskSettings_put_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY level)
1286 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1288 TRACE("%p,%d\n", iface, level);
1290 taskset->compatibility = level;
1292 return S_OK;
1295 static HRESULT WINAPI TaskSettings_get_Hidden(ITaskSettings *iface, VARIANT_BOOL *hidden)
1297 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1299 TRACE("%p,%p\n", iface, hidden);
1301 if (!hidden) return E_POINTER;
1303 *hidden = taskset->hidden ? VARIANT_TRUE : VARIANT_FALSE;
1305 return S_OK;
1308 static HRESULT WINAPI TaskSettings_put_Hidden(ITaskSettings *iface, VARIANT_BOOL hidden)
1310 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1312 TRACE("%p,%d\n", iface, hidden);
1314 taskset->hidden = hidden ? TRUE : FALSE;
1316 return S_OK;
1319 static HRESULT WINAPI TaskSettings_get_IdleSettings(ITaskSettings *iface, IIdleSettings **settings)
1321 FIXME("%p,%p: stub\n", iface, settings);
1322 return E_NOTIMPL;
1325 static HRESULT WINAPI TaskSettings_put_IdleSettings(ITaskSettings *iface, IIdleSettings *settings)
1327 FIXME("%p,%p: stub\n", iface, settings);
1328 return E_NOTIMPL;
1331 static HRESULT WINAPI TaskSettings_get_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL *run)
1333 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1335 TRACE("%p,%p\n", iface, run);
1337 if (!run) return E_POINTER;
1339 *run = taskset->run_only_if_idle ? VARIANT_TRUE : VARIANT_FALSE;
1341 return S_OK;
1344 static HRESULT WINAPI TaskSettings_put_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL run)
1346 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1348 TRACE("%p,%d\n", iface, run);
1350 taskset->run_only_if_idle = run ? TRUE : FALSE;
1352 return S_OK;
1355 static HRESULT WINAPI TaskSettings_get_WakeToRun(ITaskSettings *iface, VARIANT_BOOL *wake)
1357 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1359 TRACE("%p,%p\n", iface, wake);
1361 if (!wake) return E_POINTER;
1363 *wake = taskset->wake_to_run ? VARIANT_TRUE : VARIANT_FALSE;
1365 return S_OK;
1368 static HRESULT WINAPI TaskSettings_put_WakeToRun(ITaskSettings *iface, VARIANT_BOOL wake)
1370 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1372 TRACE("%p,%d\n", iface, wake);
1374 taskset->wake_to_run = wake ? TRUE : FALSE;
1376 return S_OK;
1379 static HRESULT WINAPI TaskSettings_get_NetworkSettings(ITaskSettings *iface, INetworkSettings **settings)
1381 FIXME("%p,%p: stub\n", iface, settings);
1382 return E_NOTIMPL;
1385 static HRESULT WINAPI TaskSettings_put_NetworkSettings(ITaskSettings *iface, INetworkSettings *settings)
1387 FIXME("%p,%p: stub\n", iface, settings);
1388 return E_NOTIMPL;
1391 static const ITaskSettingsVtbl TaskSettings_vtbl =
1393 TaskSettings_QueryInterface,
1394 TaskSettings_AddRef,
1395 TaskSettings_Release,
1396 TaskSettings_GetTypeInfoCount,
1397 TaskSettings_GetTypeInfo,
1398 TaskSettings_GetIDsOfNames,
1399 TaskSettings_Invoke,
1400 TaskSettings_get_AllowDemandStart,
1401 TaskSettings_put_AllowDemandStart,
1402 TaskSettings_get_RestartInterval,
1403 TaskSettings_put_RestartInterval,
1404 TaskSettings_get_RestartCount,
1405 TaskSettings_put_RestartCount,
1406 TaskSettings_get_MultipleInstances,
1407 TaskSettings_put_MultipleInstances,
1408 TaskSettings_get_StopIfGoingOnBatteries,
1409 TaskSettings_put_StopIfGoingOnBatteries,
1410 TaskSettings_get_DisallowStartIfOnBatteries,
1411 TaskSettings_put_DisallowStartIfOnBatteries,
1412 TaskSettings_get_AllowHardTerminate,
1413 TaskSettings_put_AllowHardTerminate,
1414 TaskSettings_get_StartWhenAvailable,
1415 TaskSettings_put_StartWhenAvailable,
1416 TaskSettings_get_XmlText,
1417 TaskSettings_put_XmlText,
1418 TaskSettings_get_RunOnlyIfNetworkAvailable,
1419 TaskSettings_put_RunOnlyIfNetworkAvailable,
1420 TaskSettings_get_ExecutionTimeLimit,
1421 TaskSettings_put_ExecutionTimeLimit,
1422 TaskSettings_get_Enabled,
1423 TaskSettings_put_Enabled,
1424 TaskSettings_get_DeleteExpiredTaskAfter,
1425 TaskSettings_put_DeleteExpiredTaskAfter,
1426 TaskSettings_get_Priority,
1427 TaskSettings_put_Priority,
1428 TaskSettings_get_Compatibility,
1429 TaskSettings_put_Compatibility,
1430 TaskSettings_get_Hidden,
1431 TaskSettings_put_Hidden,
1432 TaskSettings_get_IdleSettings,
1433 TaskSettings_put_IdleSettings,
1434 TaskSettings_get_RunOnlyIfIdle,
1435 TaskSettings_put_RunOnlyIfIdle,
1436 TaskSettings_get_WakeToRun,
1437 TaskSettings_put_WakeToRun,
1438 TaskSettings_get_NetworkSettings,
1439 TaskSettings_put_NetworkSettings
1442 static HRESULT TaskSettings_create(ITaskSettings **obj)
1444 static const WCHAR exec_time_limit[] = { 'P','T','7','2','H',0 };
1445 TaskSettings *taskset;
1447 taskset = heap_alloc(sizeof(*taskset));
1448 if (!taskset) return E_OUTOFMEMORY;
1450 taskset->ITaskSettings_iface.lpVtbl = &TaskSettings_vtbl;
1451 taskset->ref = 1;
1452 /* set the defaults */
1453 taskset->restart_interval = NULL;
1454 taskset->execution_time_limit = heap_strdupW(exec_time_limit);
1455 taskset->delete_expired_task_after = NULL;
1456 taskset->restart_count = 0;
1457 taskset->priority = 7;
1458 taskset->policy = TASK_INSTANCES_IGNORE_NEW;
1459 taskset->compatibility = TASK_COMPATIBILITY_V2;
1460 taskset->allow_on_demand_start = TRUE;
1461 taskset->stop_if_going_on_batteries = TRUE;
1462 taskset->disallow_start_if_on_batteries = TRUE;
1463 taskset->allow_hard_terminate = TRUE;
1464 taskset->start_when_available = FALSE;
1465 taskset->run_only_if_network_available = FALSE;
1466 taskset->enabled = TRUE;
1467 taskset->hidden = FALSE;
1468 taskset->run_only_if_idle = FALSE;
1469 taskset->wake_to_run = FALSE;
1471 *obj = &taskset->ITaskSettings_iface;
1473 TRACE("created %p\n", *obj);
1475 return S_OK;
1478 typedef struct
1480 IPrincipal IPrincipal_iface;
1481 LONG ref;
1482 } Principal;
1484 static inline Principal *impl_from_IPrincipal(IPrincipal *iface)
1486 return CONTAINING_RECORD(iface, Principal, IPrincipal_iface);
1489 static ULONG WINAPI Principal_AddRef(IPrincipal *iface)
1491 Principal *principal = impl_from_IPrincipal(iface);
1492 return InterlockedIncrement(&principal->ref);
1495 static ULONG WINAPI Principal_Release(IPrincipal *iface)
1497 Principal *principal = impl_from_IPrincipal(iface);
1498 LONG ref = InterlockedDecrement(&principal->ref);
1500 if (!ref)
1502 TRACE("destroying %p\n", iface);
1503 heap_free(principal);
1506 return ref;
1509 static HRESULT WINAPI Principal_QueryInterface(IPrincipal *iface, REFIID riid, void **obj)
1511 if (!riid || !obj) return E_INVALIDARG;
1513 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1515 if (IsEqualGUID(riid, &IID_IPrincipal) ||
1516 IsEqualGUID(riid, &IID_IDispatch) ||
1517 IsEqualGUID(riid, &IID_IUnknown))
1519 IPrincipal_AddRef(iface);
1520 *obj = iface;
1521 return S_OK;
1524 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1525 *obj = NULL;
1526 return E_NOINTERFACE;
1529 static HRESULT WINAPI Principal_GetTypeInfoCount(IPrincipal *iface, UINT *count)
1531 FIXME("%p,%p: stub\n", iface, count);
1532 return E_NOTIMPL;
1535 static HRESULT WINAPI Principal_GetTypeInfo(IPrincipal *iface, UINT index, LCID lcid, ITypeInfo **info)
1537 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1538 return E_NOTIMPL;
1541 static HRESULT WINAPI Principal_GetIDsOfNames(IPrincipal *iface, REFIID riid, LPOLESTR *names,
1542 UINT count, LCID lcid, DISPID *dispid)
1544 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1545 return E_NOTIMPL;
1548 static HRESULT WINAPI Principal_Invoke(IPrincipal *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1549 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1551 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1552 params, result, excepinfo, argerr);
1553 return E_NOTIMPL;
1556 static HRESULT WINAPI Principal_get_Id(IPrincipal *iface, BSTR *id)
1558 FIXME("%p,%p: stub\n", iface, id);
1559 return E_NOTIMPL;
1562 static HRESULT WINAPI Principal_put_Id(IPrincipal *iface, BSTR id)
1564 FIXME("%p,%s: stub\n", iface, debugstr_w(id));
1565 return S_OK;
1568 static HRESULT WINAPI Principal_get_DisplayName(IPrincipal *iface, BSTR *name)
1570 FIXME("%p,%p: stub\n", iface, name);
1571 return E_NOTIMPL;
1574 static HRESULT WINAPI Principal_put_DisplayName(IPrincipal *iface, BSTR name)
1576 FIXME("%p,%s: stub\n", iface, debugstr_w(name));
1577 return E_NOTIMPL;
1580 static HRESULT WINAPI Principal_get_UserId(IPrincipal *iface, BSTR *user_id)
1582 FIXME("%p,%p: stub\n", iface, user_id);
1583 return E_NOTIMPL;
1586 static HRESULT WINAPI Principal_put_UserId(IPrincipal *iface, BSTR user_id)
1588 FIXME("%p,%s: stub\n", iface, debugstr_w(user_id));
1589 return S_OK;
1592 static HRESULT WINAPI Principal_get_LogonType(IPrincipal *iface, TASK_LOGON_TYPE *logon_type)
1594 FIXME("%p,%p: stub\n", iface, logon_type);
1595 return E_NOTIMPL;
1598 static HRESULT WINAPI Principal_put_LogonType(IPrincipal *iface, TASK_LOGON_TYPE logon_type)
1600 FIXME("%p,%u: stub\n", iface, logon_type);
1601 return E_NOTIMPL;
1604 static HRESULT WINAPI Principal_get_GroupId(IPrincipal *iface, BSTR *group_id)
1606 FIXME("%p,%p: stub\n", iface, group_id);
1607 return E_NOTIMPL;
1610 static HRESULT WINAPI Principal_put_GroupId(IPrincipal *iface, BSTR group_id)
1612 FIXME("%p,%s: stub\n", iface, debugstr_w(group_id));
1613 return E_NOTIMPL;
1616 static HRESULT WINAPI Principal_get_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE *run_level)
1618 FIXME("%p,%p: stub\n", iface, run_level);
1619 return E_NOTIMPL;
1622 static HRESULT WINAPI Principal_put_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE run_level)
1624 FIXME("%p,%u: stub\n", iface, run_level);
1625 return E_NOTIMPL;
1628 static const IPrincipalVtbl Principal_vtbl =
1630 Principal_QueryInterface,
1631 Principal_AddRef,
1632 Principal_Release,
1633 Principal_GetTypeInfoCount,
1634 Principal_GetTypeInfo,
1635 Principal_GetIDsOfNames,
1636 Principal_Invoke,
1637 Principal_get_Id,
1638 Principal_put_Id,
1639 Principal_get_DisplayName,
1640 Principal_put_DisplayName,
1641 Principal_get_UserId,
1642 Principal_put_UserId,
1643 Principal_get_LogonType,
1644 Principal_put_LogonType,
1645 Principal_get_GroupId,
1646 Principal_put_GroupId,
1647 Principal_get_RunLevel,
1648 Principal_put_RunLevel
1651 static HRESULT Principal_create(IPrincipal **obj)
1653 Principal *principal;
1655 principal = heap_alloc(sizeof(*principal));
1656 if (!principal) return E_OUTOFMEMORY;
1658 principal->IPrincipal_iface.lpVtbl = &Principal_vtbl;
1659 principal->ref = 1;
1661 *obj = &principal->IPrincipal_iface;
1663 TRACE("created %p\n", *obj);
1665 return S_OK;
1668 typedef struct
1670 IExecAction IExecAction_iface;
1671 LONG ref;
1672 WCHAR *path;
1673 WCHAR *directory;
1674 WCHAR *args;
1675 WCHAR *id;
1676 } ExecAction;
1678 static inline ExecAction *impl_from_IExecAction(IExecAction *iface)
1680 return CONTAINING_RECORD(iface, ExecAction, IExecAction_iface);
1683 static ULONG WINAPI ExecAction_AddRef(IExecAction *iface)
1685 ExecAction *action = impl_from_IExecAction(iface);
1686 return InterlockedIncrement(&action->ref);
1689 static ULONG WINAPI ExecAction_Release(IExecAction *iface)
1691 ExecAction *action = impl_from_IExecAction(iface);
1692 LONG ref = InterlockedDecrement(&action->ref);
1694 if (!ref)
1696 TRACE("destroying %p\n", iface);
1697 heap_free(action->path);
1698 heap_free(action->directory);
1699 heap_free(action->args);
1700 heap_free(action->id);
1701 heap_free(action);
1704 return ref;
1707 static HRESULT WINAPI ExecAction_QueryInterface(IExecAction *iface, REFIID riid, void **obj)
1709 if (!riid || !obj) return E_INVALIDARG;
1711 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1713 if (IsEqualGUID(riid, &IID_IExecAction) ||
1714 IsEqualGUID(riid, &IID_IAction) ||
1715 IsEqualGUID(riid, &IID_IDispatch) ||
1716 IsEqualGUID(riid, &IID_IUnknown))
1718 IExecAction_AddRef(iface);
1719 *obj = iface;
1720 return S_OK;
1723 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1724 *obj = NULL;
1725 return E_NOINTERFACE;
1728 static HRESULT WINAPI ExecAction_GetTypeInfoCount(IExecAction *iface, UINT *count)
1730 FIXME("%p,%p: stub\n", iface, count);
1731 return E_NOTIMPL;
1734 static HRESULT WINAPI ExecAction_GetTypeInfo(IExecAction *iface, UINT index, LCID lcid, ITypeInfo **info)
1736 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1737 return E_NOTIMPL;
1740 static HRESULT WINAPI ExecAction_GetIDsOfNames(IExecAction *iface, REFIID riid, LPOLESTR *names,
1741 UINT count, LCID lcid, DISPID *dispid)
1743 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1744 return E_NOTIMPL;
1747 static HRESULT WINAPI ExecAction_Invoke(IExecAction *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1748 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1750 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1751 params, result, excepinfo, argerr);
1752 return E_NOTIMPL;
1755 static HRESULT WINAPI ExecAction_get_Id(IExecAction *iface, BSTR *id)
1757 ExecAction *action = impl_from_IExecAction(iface);
1759 TRACE("%p,%p\n", iface, id);
1761 if (!id) return E_POINTER;
1763 if (!action->id) *id = NULL;
1764 else if (!(*id = SysAllocString(action->id))) return E_OUTOFMEMORY;
1766 return S_OK;
1769 static HRESULT WINAPI ExecAction_put_Id(IExecAction *iface, BSTR id)
1771 ExecAction *action = impl_from_IExecAction(iface);
1772 WCHAR *str = NULL;
1774 TRACE("%p,%s\n", iface, debugstr_w(id));
1776 if (id && !(str = heap_strdupW((id)))) return E_OUTOFMEMORY;
1777 heap_free(action->id);
1778 action->id = str;
1780 return S_OK;
1783 static HRESULT WINAPI ExecAction_get_Type(IExecAction *iface, TASK_ACTION_TYPE *type)
1785 TRACE("%p,%p\n", iface, type);
1787 if (!type) return E_POINTER;
1789 *type = TASK_ACTION_EXEC;
1791 return S_OK;
1794 static HRESULT WINAPI ExecAction_get_Path(IExecAction *iface, BSTR *path)
1796 ExecAction *action = impl_from_IExecAction(iface);
1798 TRACE("%p,%p\n", iface, path);
1800 if (!path) return E_POINTER;
1802 if (!action->path) *path = NULL;
1803 else if (!(*path = SysAllocString(action->path))) return E_OUTOFMEMORY;
1805 return S_OK;
1808 static HRESULT WINAPI ExecAction_put_Path(IExecAction *iface, BSTR path)
1810 ExecAction *action = impl_from_IExecAction(iface);
1811 WCHAR *str = NULL;
1813 TRACE("%p,%s\n", iface, debugstr_w(path));
1815 if (path && !(str = heap_strdupW((path)))) return E_OUTOFMEMORY;
1816 heap_free(action->path);
1817 action->path = str;
1819 return S_OK;
1822 static HRESULT WINAPI ExecAction_get_Arguments(IExecAction *iface, BSTR *arguments)
1824 ExecAction *action = impl_from_IExecAction(iface);
1826 TRACE("%p,%p\n", iface, arguments);
1828 if (!arguments) return E_POINTER;
1830 if (!action->args) *arguments = NULL;
1831 else if (!(*arguments = SysAllocString(action->args))) return E_OUTOFMEMORY;
1833 return S_OK;
1836 static HRESULT WINAPI ExecAction_put_Arguments(IExecAction *iface, BSTR arguments)
1838 ExecAction *action = impl_from_IExecAction(iface);
1839 WCHAR *str = NULL;
1841 TRACE("%p,%s\n", iface, debugstr_w(arguments));
1843 if (arguments && !(str = heap_strdupW((arguments)))) return E_OUTOFMEMORY;
1844 heap_free(action->args);
1845 action->args = str;
1847 return S_OK;
1850 static HRESULT WINAPI ExecAction_get_WorkingDirectory(IExecAction *iface, BSTR *directory)
1852 ExecAction *action = impl_from_IExecAction(iface);
1854 TRACE("%p,%p\n", iface, directory);
1856 if (!directory) return E_POINTER;
1858 if (!action->directory) *directory = NULL;
1859 else if (!(*directory = SysAllocString(action->directory))) return E_OUTOFMEMORY;
1861 return S_OK;
1864 static HRESULT WINAPI ExecAction_put_WorkingDirectory(IExecAction *iface, BSTR directory)
1866 ExecAction *action = impl_from_IExecAction(iface);
1867 WCHAR *str = NULL;
1869 TRACE("%p,%s\n", iface, debugstr_w(directory));
1871 if (directory && !(str = heap_strdupW((directory)))) return E_OUTOFMEMORY;
1872 heap_free(action->directory);
1873 action->directory = str;
1875 return S_OK;
1878 static const IExecActionVtbl Action_vtbl =
1880 ExecAction_QueryInterface,
1881 ExecAction_AddRef,
1882 ExecAction_Release,
1883 ExecAction_GetTypeInfoCount,
1884 ExecAction_GetTypeInfo,
1885 ExecAction_GetIDsOfNames,
1886 ExecAction_Invoke,
1887 ExecAction_get_Id,
1888 ExecAction_put_Id,
1889 ExecAction_get_Type,
1890 ExecAction_get_Path,
1891 ExecAction_put_Path,
1892 ExecAction_get_Arguments,
1893 ExecAction_put_Arguments,
1894 ExecAction_get_WorkingDirectory,
1895 ExecAction_put_WorkingDirectory
1898 static HRESULT ExecAction_create(IExecAction **obj)
1900 ExecAction *action;
1902 action = heap_alloc(sizeof(*action));
1903 if (!action) return E_OUTOFMEMORY;
1905 action->IExecAction_iface.lpVtbl = &Action_vtbl;
1906 action->ref = 1;
1907 action->path = NULL;
1908 action->directory = NULL;
1909 action->args = NULL;
1910 action->id = NULL;
1912 *obj = &action->IExecAction_iface;
1914 TRACE("created %p\n", *obj);
1916 return S_OK;
1919 typedef struct
1921 IActionCollection IActionCollection_iface;
1922 LONG ref;
1923 } Actions;
1925 static inline Actions *impl_from_IActionCollection(IActionCollection *iface)
1927 return CONTAINING_RECORD(iface, Actions, IActionCollection_iface);
1930 static ULONG WINAPI Actions_AddRef(IActionCollection *iface)
1932 Actions *actions = impl_from_IActionCollection(iface);
1933 return InterlockedIncrement(&actions->ref);
1936 static ULONG WINAPI Actions_Release(IActionCollection *iface)
1938 Actions *actions = impl_from_IActionCollection(iface);
1939 LONG ref = InterlockedDecrement(&actions->ref);
1941 if (!ref)
1943 TRACE("destroying %p\n", iface);
1944 heap_free(actions);
1947 return ref;
1950 static HRESULT WINAPI Actions_QueryInterface(IActionCollection *iface, REFIID riid, void **obj)
1952 if (!riid || !obj) return E_INVALIDARG;
1954 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1956 if (IsEqualGUID(riid, &IID_IActionCollection) ||
1957 IsEqualGUID(riid, &IID_IDispatch) ||
1958 IsEqualGUID(riid, &IID_IUnknown))
1960 IActionCollection_AddRef(iface);
1961 *obj = iface;
1962 return S_OK;
1965 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1966 *obj = NULL;
1967 return E_NOINTERFACE;
1970 static HRESULT WINAPI Actions_GetTypeInfoCount(IActionCollection *iface, UINT *count)
1972 FIXME("%p,%p: stub\n", iface, count);
1973 return E_NOTIMPL;
1976 static HRESULT WINAPI Actions_GetTypeInfo(IActionCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
1978 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1979 return E_NOTIMPL;
1982 static HRESULT WINAPI Actions_GetIDsOfNames(IActionCollection *iface, REFIID riid, LPOLESTR *names,
1983 UINT count, LCID lcid, DISPID *dispid)
1985 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1986 return E_NOTIMPL;
1989 static HRESULT WINAPI Actions_Invoke(IActionCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1990 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1992 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1993 params, result, excepinfo, argerr);
1994 return E_NOTIMPL;
1997 static HRESULT WINAPI Actions_get_Count(IActionCollection *iface, LONG *count)
1999 FIXME("%p,%p: stub\n", iface, count);
2000 return E_NOTIMPL;
2003 static HRESULT WINAPI Actions_get_Item(IActionCollection *iface, LONG index, IAction **action)
2005 FIXME("%p,%d,%p: stub\n", iface, index, action);
2006 return E_NOTIMPL;
2009 static HRESULT WINAPI Actions_get__NewEnum(IActionCollection *iface, IUnknown **penum)
2011 FIXME("%p,%p: stub\n", iface, penum);
2012 return E_NOTIMPL;
2015 static HRESULT WINAPI Actions_get_XmlText(IActionCollection *iface, BSTR *xml)
2017 FIXME("%p,%p: stub\n", iface, xml);
2018 return E_NOTIMPL;
2021 static HRESULT WINAPI Actions_put_XmlText(IActionCollection *iface, BSTR xml)
2023 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
2024 return E_NOTIMPL;
2027 static HRESULT WINAPI Actions_Create(IActionCollection *iface, TASK_ACTION_TYPE type, IAction **action)
2029 TRACE("%p,%u,%p\n", iface, type, action);
2031 switch (type)
2033 case TASK_ACTION_EXEC:
2034 return ExecAction_create((IExecAction **)action);
2036 default:
2037 FIXME("unimplemented type %u\n", type);
2038 return E_NOTIMPL;
2042 static HRESULT WINAPI Actions_Remove(IActionCollection *iface, VARIANT index)
2044 FIXME("%p,%s: stub\n", iface, debugstr_variant(&index));
2045 return E_NOTIMPL;
2048 static HRESULT WINAPI Actions_Clear(IActionCollection *iface)
2050 FIXME("%p: stub\n", iface);
2051 return E_NOTIMPL;
2054 static HRESULT WINAPI Actions_get_Context(IActionCollection *iface, BSTR *ctx)
2056 FIXME("%p,%p: stub\n", iface, ctx);
2057 return E_NOTIMPL;
2060 static HRESULT WINAPI Actions_put_Context(IActionCollection *iface, BSTR ctx)
2062 FIXME("%p,%s: stub\n", iface, debugstr_w(ctx));
2063 return S_OK;
2066 static const IActionCollectionVtbl Actions_vtbl =
2068 Actions_QueryInterface,
2069 Actions_AddRef,
2070 Actions_Release,
2071 Actions_GetTypeInfoCount,
2072 Actions_GetTypeInfo,
2073 Actions_GetIDsOfNames,
2074 Actions_Invoke,
2075 Actions_get_Count,
2076 Actions_get_Item,
2077 Actions_get__NewEnum,
2078 Actions_get_XmlText,
2079 Actions_put_XmlText,
2080 Actions_Create,
2081 Actions_Remove,
2082 Actions_Clear,
2083 Actions_get_Context,
2084 Actions_put_Context
2087 static HRESULT Actions_create(IActionCollection **obj)
2089 Actions *actions;
2091 actions = heap_alloc(sizeof(*actions));
2092 if (!actions) return E_OUTOFMEMORY;
2094 actions->IActionCollection_iface.lpVtbl = &Actions_vtbl;
2095 actions->ref = 1;
2097 *obj = &actions->IActionCollection_iface;
2099 TRACE("created %p\n", *obj);
2101 return S_OK;
2104 typedef struct
2106 ITaskDefinition ITaskDefinition_iface;
2107 LONG ref;
2108 IRegistrationInfo *reginfo;
2109 ITaskSettings *taskset;
2110 ITriggerCollection *triggers;
2111 IPrincipal *principal;
2112 IActionCollection *actions;
2113 } TaskDefinition;
2115 static inline TaskDefinition *impl_from_ITaskDefinition(ITaskDefinition *iface)
2117 return CONTAINING_RECORD(iface, TaskDefinition, ITaskDefinition_iface);
2120 static ULONG WINAPI TaskDefinition_AddRef(ITaskDefinition *iface)
2122 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2123 return InterlockedIncrement(&taskdef->ref);
2126 static ULONG WINAPI TaskDefinition_Release(ITaskDefinition *iface)
2128 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2129 LONG ref = InterlockedDecrement(&taskdef->ref);
2131 if (!ref)
2133 TRACE("destroying %p\n", iface);
2135 if (taskdef->reginfo)
2136 IRegistrationInfo_Release(taskdef->reginfo);
2137 if (taskdef->taskset)
2138 ITaskSettings_Release(taskdef->taskset);
2139 if (taskdef->triggers)
2140 ITriggerCollection_Release(taskdef->triggers);
2141 if (taskdef->principal)
2142 IPrincipal_Release(taskdef->principal);
2143 if (taskdef->actions)
2144 IActionCollection_Release(taskdef->actions);
2146 heap_free(taskdef);
2149 return ref;
2152 static HRESULT WINAPI TaskDefinition_QueryInterface(ITaskDefinition *iface, REFIID riid, void **obj)
2154 if (!riid || !obj) return E_INVALIDARG;
2156 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
2158 if (IsEqualGUID(riid, &IID_ITaskDefinition) ||
2159 IsEqualGUID(riid, &IID_IDispatch) ||
2160 IsEqualGUID(riid, &IID_IUnknown))
2162 ITaskDefinition_AddRef(iface);
2163 *obj = iface;
2164 return S_OK;
2167 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
2168 *obj = NULL;
2169 return E_NOINTERFACE;
2172 static HRESULT WINAPI TaskDefinition_GetTypeInfoCount(ITaskDefinition *iface, UINT *count)
2174 FIXME("%p,%p: stub\n", iface, count);
2175 return E_NOTIMPL;
2178 static HRESULT WINAPI TaskDefinition_GetTypeInfo(ITaskDefinition *iface, UINT index, LCID lcid, ITypeInfo **info)
2180 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
2181 return E_NOTIMPL;
2184 static HRESULT WINAPI TaskDefinition_GetIDsOfNames(ITaskDefinition *iface, REFIID riid, LPOLESTR *names,
2185 UINT count, LCID lcid, DISPID *dispid)
2187 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
2188 return E_NOTIMPL;
2191 static HRESULT WINAPI TaskDefinition_Invoke(ITaskDefinition *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
2192 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
2194 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
2195 params, result, excepinfo, argerr);
2196 return E_NOTIMPL;
2199 static HRESULT WINAPI TaskDefinition_get_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo **info)
2201 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2202 HRESULT hr;
2204 TRACE("%p,%p\n", iface, info);
2206 if (!info) return E_POINTER;
2208 if (!taskdef->reginfo)
2210 hr = RegistrationInfo_create(&taskdef->reginfo);
2211 if (hr != S_OK) return hr;
2214 IRegistrationInfo_AddRef(taskdef->reginfo);
2215 *info = taskdef->reginfo;
2217 return S_OK;
2220 static HRESULT WINAPI TaskDefinition_put_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo *info)
2222 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2224 TRACE("%p,%p\n", iface, info);
2226 if (!info) return E_POINTER;
2228 if (taskdef->reginfo)
2229 IRegistrationInfo_Release(taskdef->reginfo);
2231 IRegistrationInfo_AddRef(info);
2232 taskdef->reginfo = info;
2234 return S_OK;
2237 static HRESULT WINAPI TaskDefinition_get_Triggers(ITaskDefinition *iface, ITriggerCollection **triggers)
2239 TaskDefinition *This = impl_from_ITaskDefinition(iface);
2241 TRACE("%p,%p\n", This, triggers);
2243 if (!This->triggers)
2245 trigger_collection *collection;
2247 collection = heap_alloc(sizeof(*collection));
2248 if (!collection) return E_OUTOFMEMORY;
2250 collection->ITriggerCollection_iface.lpVtbl = &TriggerCollection_vtbl;
2251 collection->ref = 1;
2252 This->triggers = &collection->ITriggerCollection_iface;
2255 ITriggerCollection_AddRef(*triggers = This->triggers);
2256 return S_OK;
2259 static HRESULT WINAPI TaskDefinition_put_Triggers(ITaskDefinition *iface, ITriggerCollection *triggers)
2261 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2263 TRACE("%p,%p\n", iface, triggers);
2265 if (!triggers) return E_POINTER;
2267 if (taskdef->triggers)
2268 ITriggerCollection_Release(taskdef->triggers);
2270 ITriggerCollection_AddRef(triggers);
2271 taskdef->triggers = triggers;
2273 return S_OK;
2276 static HRESULT WINAPI TaskDefinition_get_Settings(ITaskDefinition *iface, ITaskSettings **settings)
2278 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2279 HRESULT hr;
2281 TRACE("%p,%p\n", iface, settings);
2283 if (!settings) return E_POINTER;
2285 if (!taskdef->taskset)
2287 hr = TaskSettings_create(&taskdef->taskset);
2288 if (hr != S_OK) return hr;
2291 ITaskSettings_AddRef(taskdef->taskset);
2292 *settings = taskdef->taskset;
2294 return S_OK;
2297 static HRESULT WINAPI TaskDefinition_put_Settings(ITaskDefinition *iface, ITaskSettings *settings)
2299 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2301 TRACE("%p,%p\n", iface, settings);
2303 if (!settings) return E_POINTER;
2305 if (taskdef->taskset)
2306 ITaskSettings_Release(taskdef->taskset);
2308 ITaskSettings_AddRef(settings);
2309 taskdef->taskset = settings;
2311 return S_OK;
2314 static HRESULT WINAPI TaskDefinition_get_Data(ITaskDefinition *iface, BSTR *data)
2316 FIXME("%p,%p: stub\n", iface, data);
2317 return E_NOTIMPL;
2320 static HRESULT WINAPI TaskDefinition_put_Data(ITaskDefinition *iface, BSTR data)
2322 FIXME("%p,%p: stub\n", iface, data);
2323 return E_NOTIMPL;
2326 static HRESULT WINAPI TaskDefinition_get_Principal(ITaskDefinition *iface, IPrincipal **principal)
2328 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2329 HRESULT hr;
2331 TRACE("%p,%p\n", iface, principal);
2333 if (!principal) return E_POINTER;
2335 if (!taskdef->principal)
2337 hr = Principal_create(&taskdef->principal);
2338 if (hr != S_OK) return hr;
2341 IPrincipal_AddRef(taskdef->principal);
2342 *principal = taskdef->principal;
2344 return S_OK;
2347 static HRESULT WINAPI TaskDefinition_put_Principal(ITaskDefinition *iface, IPrincipal *principal)
2349 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2351 TRACE("%p,%p\n", iface, principal);
2353 if (!principal) return E_POINTER;
2355 if (taskdef->principal)
2356 IPrincipal_Release(taskdef->principal);
2358 IPrincipal_AddRef(principal);
2359 taskdef->principal = principal;
2361 return S_OK;
2364 static HRESULT WINAPI TaskDefinition_get_Actions(ITaskDefinition *iface, IActionCollection **actions)
2366 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2367 HRESULT hr;
2369 TRACE("%p,%p\n", iface, actions);
2371 if (!actions) return E_POINTER;
2373 if (!taskdef->actions)
2375 hr = Actions_create(&taskdef->actions);
2376 if (hr != S_OK) return hr;
2379 IActionCollection_AddRef(taskdef->actions);
2380 *actions = taskdef->actions;
2382 return S_OK;
2385 static HRESULT WINAPI TaskDefinition_put_Actions(ITaskDefinition *iface, IActionCollection *actions)
2387 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2389 TRACE("%p,%p\n", iface, actions);
2391 if (!actions) return E_POINTER;
2393 if (taskdef->actions)
2394 IActionCollection_Release(taskdef->actions);
2396 IActionCollection_AddRef(actions);
2397 taskdef->actions = actions;
2399 return S_OK;
2402 static const WCHAR Task[] = {'T','a','s','k',0};
2403 static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
2404 static const WCHAR v1_0[] = {'1','.','0',0};
2405 static const WCHAR v1_1[] = {'1','.','1',0};
2406 static const WCHAR v1_2[] = {'1','.','2',0};
2407 static const WCHAR v1_3[] = {'1','.','3',0};
2408 static const WCHAR xmlns[] = {'x','m','l','n','s',0};
2409 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};
2410 static const WCHAR RegistrationInfo[] = {'R','e','g','i','s','t','r','a','t','i','o','n','I','n','f','o',0};
2411 static const WCHAR Author[] = {'A','u','t','h','o','r',0};
2412 static const WCHAR Description[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
2413 static const WCHAR Source[] = {'S','o','u','r','c','e',0};
2414 static const WCHAR Date[] = {'D','a','t','e',0};
2415 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
2416 static const WCHAR Documentation[] = {'D','o','c','u','m','e','n','t','a','t','i','o','n',0};
2417 static const WCHAR URI[] = {'U','R','I',0};
2418 static const WCHAR SecurityDescriptor[] = {'S','e','c','u','r','i','t','y','D','e','s','c','r','i','p','t','o','r',0};
2419 static const WCHAR Settings[] = {'S','e','t','t','i','n','g','s',0};
2420 static const WCHAR Triggers[] = {'T','r','i','g','g','e','r','s',0};
2421 static const WCHAR Principals[] = {'P','r','i','n','c','i','p','a','l','s',0};
2422 static const WCHAR principalW[] = {'P','r','i','n','c','i','p','a','l',0};
2423 static const WCHAR id[] = {'i','d',0};
2424 static const WCHAR UserId[] = {'U','s','e','r','I','d',0};
2425 static const WCHAR LogonType[] = {'L','o','g','o','n','T','y','p','e',0};
2426 static const WCHAR GroupId[] = {'G','r','o','u','p','I','d',0};
2427 static const WCHAR DisplayName[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
2428 static const WCHAR HighestAvailable[] = {'H','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
2429 static const WCHAR Password[] = {'P','a','s','s','w','o','r','d',0};
2430 static const WCHAR S4U[] = {'S','4','U',0};
2431 static const WCHAR InteractiveToken[] = {'I','n','t','e','r','a','c','t','i','v','e','T','o','k','e','n',0};
2432 static const WCHAR RunLevel[] = {'R','u','n','L','e','v','e','l',0};
2433 static const WCHAR LeastPrivilege[] = {'L','e','a','s','t','P','r','i','v','i','l','e','g','e',0};
2434 static const WCHAR actionsW[] = {'A','c','t','i','o','n','s',0};
2435 static const WCHAR Exec[] = {'E','x','e','c',0};
2436 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};
2437 static const WCHAR IgnoreNew[] = {'I','g','n','o','r','e','N','e','w',0};
2438 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};
2439 static const WCHAR AllowStartOnDemand[] = {'A','l','l','o','w','S','t','a','r','t','O','n','D','e','m','a','n','d',0};
2440 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};
2441 static const WCHAR AllowHardTerminate[] = {'A','l','l','o','w','H','a','r','d','T','e','r','m','i','n','a','t','e',0};
2442 static const WCHAR StartWhenAvailable[] = {'S','t','a','r','t','W','h','e','n','A','v','a','i','l','a','b','l','e',0};
2443 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};
2444 static const WCHAR Enabled[] = {'E','n','a','b','l','e','d',0};
2445 static const WCHAR Hidden[] = {'H','i','d','d','e','n',0};
2446 static const WCHAR RunOnlyIfIdle[] = {'R','u','n','O','n','l','y','I','f','I','d','l','e',0};
2447 static const WCHAR WakeToRun[] = {'W','a','k','e','T','o','R','u','n',0};
2448 static const WCHAR ExecutionTimeLimit[] = {'E','x','e','c','u','t','i','o','n','T','i','m','e','L','i','m','i','t',0};
2449 static const WCHAR Priority[] = {'P','r','i','o','r','i','t','y',0};
2450 static const WCHAR IdleSettings[] = {'I','d','l','e','S','e','t','t','i','n','g','s',0};
2452 static int xml_indent;
2454 static inline void push_indent(void)
2456 xml_indent += 2;
2459 static inline void pop_indent(void)
2461 xml_indent -= 2;
2464 static inline HRESULT write_stringW(IStream *stream, const WCHAR *str)
2466 return IStream_Write(stream, str, lstrlenW(str) * sizeof(WCHAR), NULL);
2469 static void write_indent(IStream *stream)
2471 static const WCHAR spacesW[] = {' ',' ',0};
2472 int i;
2473 for (i = 0; i < xml_indent; i += 2)
2474 write_stringW(stream, spacesW);
2477 static const WCHAR start_element[] = {'<',0};
2478 static const WCHAR start_end_element[] = {'<','/',0};
2479 static const WCHAR close_element[] = {'>',0};
2480 static const WCHAR end_empty_element[] = {'/','>',0};
2481 static const WCHAR eol[] = {'\n',0};
2482 static const WCHAR spaceW[] = {' ',0};
2483 static const WCHAR equalW[] = {'=',0};
2484 static const WCHAR quoteW[] = {'"',0};
2486 static inline HRESULT write_empty_element(IStream *stream, const WCHAR *name)
2488 write_indent(stream);
2489 write_stringW(stream, start_element);
2490 write_stringW(stream, name);
2491 write_stringW(stream, end_empty_element);
2492 return write_stringW(stream, eol);
2495 static inline HRESULT write_element(IStream *stream, const WCHAR *name)
2497 write_indent(stream);
2498 write_stringW(stream, start_element);
2499 write_stringW(stream, name);
2500 write_stringW(stream, close_element);
2501 return write_stringW(stream, eol);
2504 static inline HRESULT write_element_end(IStream *stream, const WCHAR *name)
2506 write_indent(stream);
2507 write_stringW(stream, start_end_element);
2508 write_stringW(stream, name);
2509 write_stringW(stream, close_element);
2510 return write_stringW(stream, eol);
2513 static inline HRESULT write_text_value(IStream *stream, const WCHAR *name, const WCHAR *value)
2515 write_indent(stream);
2516 write_stringW(stream, start_element);
2517 write_stringW(stream, name);
2518 write_stringW(stream, close_element);
2519 write_stringW(stream, value);
2520 write_stringW(stream, start_end_element);
2521 write_stringW(stream, name);
2522 write_stringW(stream, close_element);
2523 return write_stringW(stream, eol);
2526 static HRESULT write_task_attributes(IStream *stream, ITaskDefinition *taskdef)
2528 HRESULT hr;
2529 ITaskSettings *taskset;
2530 TASK_COMPATIBILITY level;
2531 const WCHAR *compatibility;
2533 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
2534 if (hr != S_OK) return hr;
2536 hr = ITaskSettings_get_Compatibility(taskset, &level);
2537 if (hr != S_OK) level = TASK_COMPATIBILITY_V2_1;
2539 ITaskSettings_Release(taskset);
2541 switch (level)
2543 case TASK_COMPATIBILITY_AT:
2544 compatibility = v1_0;
2545 break;
2546 case TASK_COMPATIBILITY_V1:
2547 compatibility = v1_1;
2548 break;
2549 case TASK_COMPATIBILITY_V2:
2550 compatibility = v1_2;
2551 break;
2552 default:
2553 compatibility = v1_3;
2554 break;
2557 write_stringW(stream, start_element);
2558 write_stringW(stream, Task);
2559 write_stringW(stream, spaceW);
2560 write_stringW(stream, version);
2561 write_stringW(stream, equalW);
2562 write_stringW(stream, quoteW);
2563 write_stringW(stream, compatibility);
2564 write_stringW(stream, quoteW);
2565 write_stringW(stream, spaceW);
2566 write_stringW(stream, xmlns);
2567 write_stringW(stream, equalW);
2568 write_stringW(stream, quoteW);
2569 write_stringW(stream, task_ns);
2570 write_stringW(stream, quoteW);
2571 write_stringW(stream, close_element);
2572 return write_stringW(stream, eol);
2575 static HRESULT write_registration_info(IStream *stream, IRegistrationInfo *reginfo)
2577 HRESULT hr;
2578 BSTR bstr;
2579 VARIANT var;
2581 if (!reginfo)
2582 return write_empty_element(stream, RegistrationInfo);
2584 hr = write_element(stream, RegistrationInfo);
2585 if (hr != S_OK) return hr;
2587 push_indent();
2589 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
2590 if (hr == S_OK && bstr)
2592 hr = write_text_value(stream, Source, bstr);
2593 SysFreeString(bstr);
2594 if (hr != S_OK) return hr;
2596 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
2597 if (hr == S_OK && bstr)
2599 hr = write_text_value(stream, Date, bstr);
2600 SysFreeString(bstr);
2601 if (hr != S_OK) return hr;
2603 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
2604 if (hr == S_OK && bstr)
2606 hr = write_text_value(stream, Author, bstr);
2607 SysFreeString(bstr);
2608 if (hr != S_OK) return hr;
2610 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
2611 if (hr == S_OK && bstr)
2613 hr = write_text_value(stream, Version, bstr);
2614 SysFreeString(bstr);
2615 if (hr != S_OK) return hr;
2617 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
2618 if (hr == S_OK && bstr)
2620 hr = write_text_value(stream, Description, bstr);
2621 SysFreeString(bstr);
2622 if (hr != S_OK) return hr;
2624 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
2625 if (hr == S_OK && bstr)
2627 hr = write_text_value(stream, Documentation, bstr);
2628 SysFreeString(bstr);
2629 if (hr != S_OK) return hr;
2631 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
2632 if (hr == S_OK && bstr)
2634 hr = write_text_value(stream, URI, bstr);
2635 SysFreeString(bstr);
2636 if (hr != S_OK) return hr;
2638 hr = IRegistrationInfo_get_SecurityDescriptor(reginfo, &var);
2639 if (hr == S_OK)
2641 if (V_VT(&var) == VT_BSTR)
2643 hr = write_text_value(stream, SecurityDescriptor, V_BSTR(&var));
2644 VariantClear(&var);
2645 if (hr != S_OK) return hr;
2647 else
2648 FIXME("SecurityInfo variant type %d is not supported\n", V_VT(&var));
2651 pop_indent();
2653 return write_element_end(stream, RegistrationInfo);
2656 static HRESULT write_principal(IStream *stream, IPrincipal *principal)
2658 HRESULT hr;
2659 BSTR bstr;
2660 TASK_LOGON_TYPE logon;
2661 TASK_RUNLEVEL_TYPE level;
2663 if (!principal)
2664 return write_empty_element(stream, Principals);
2666 hr = write_element(stream, Principals);
2667 if (hr != S_OK) return hr;
2669 push_indent();
2671 hr = IPrincipal_get_Id(principal, &bstr);
2672 if (hr == S_OK)
2674 write_indent(stream);
2675 write_stringW(stream, start_element);
2676 write_stringW(stream, principalW);
2677 write_stringW(stream, spaceW);
2678 write_stringW(stream, id);
2679 write_stringW(stream, equalW);
2680 write_stringW(stream, quoteW);
2681 write_stringW(stream, bstr);
2682 write_stringW(stream, quoteW);
2683 write_stringW(stream, close_element);
2684 write_stringW(stream, eol);
2685 SysFreeString(bstr);
2687 else
2688 write_element(stream, principalW);
2690 push_indent();
2692 hr = IPrincipal_get_GroupId(principal, &bstr);
2693 if (hr == S_OK)
2695 hr = write_text_value(stream, GroupId, bstr);
2696 SysFreeString(bstr);
2697 if (hr != S_OK) return hr;
2699 hr = IPrincipal_get_DisplayName(principal, &bstr);
2700 if (hr == S_OK)
2702 hr = write_text_value(stream, DisplayName, bstr);
2703 SysFreeString(bstr);
2704 if (hr != S_OK) return hr;
2706 hr = IPrincipal_get_UserId(principal, &bstr);
2707 if (hr == S_OK && lstrlenW(bstr))
2709 hr = write_text_value(stream, UserId, bstr);
2710 SysFreeString(bstr);
2711 if (hr != S_OK) return hr;
2713 hr = IPrincipal_get_RunLevel(principal, &level);
2714 if (hr == S_OK)
2716 const WCHAR *level_str = NULL;
2718 switch (level)
2720 case TASK_RUNLEVEL_HIGHEST:
2721 level_str = HighestAvailable;
2722 break;
2723 case TASK_RUNLEVEL_LUA:
2724 level_str = LeastPrivilege;
2725 break;
2726 default:
2727 FIXME("Principal run level %d\n", level);
2728 break;
2731 if (level_str)
2733 hr = write_text_value(stream, RunLevel, level_str);
2734 if (hr != S_OK) return hr;
2737 hr = IPrincipal_get_LogonType(principal, &logon);
2738 if (hr == S_OK)
2740 const WCHAR *logon_str = NULL;
2742 switch (logon)
2744 case TASK_LOGON_PASSWORD:
2745 logon_str = Password;
2746 break;
2747 case TASK_LOGON_S4U:
2748 logon_str = S4U;
2749 break;
2750 case TASK_LOGON_INTERACTIVE_TOKEN:
2751 logon_str = InteractiveToken;
2752 break;
2753 default:
2754 FIXME("Principal logon type %d\n", logon);
2755 break;
2758 if (logon_str)
2760 hr = write_text_value(stream, LogonType, logon_str);
2761 if (hr != S_OK) return hr;
2765 pop_indent();
2766 write_element_end(stream, principalW);
2768 pop_indent();
2769 return write_element_end(stream, Principals);
2772 static HRESULT write_settings(IStream *stream, ITaskSettings *settings)
2774 if (!settings)
2775 return write_empty_element(stream, Settings);
2777 FIXME("stub\n");
2778 return S_OK;
2781 static HRESULT write_triggers(IStream *stream, ITriggerCollection *triggers)
2783 if (!triggers)
2784 return write_empty_element(stream, Triggers);
2786 FIXME("stub\n");
2787 return S_OK;
2790 static HRESULT write_actions(IStream *stream, IActionCollection *actions)
2792 if (!actions)
2794 write_element(stream, actionsW);
2795 push_indent();
2796 write_empty_element(stream, Exec);
2797 pop_indent();
2798 return write_element_end(stream, actionsW);
2801 FIXME("stub\n");
2802 return S_OK;
2805 static HRESULT WINAPI TaskDefinition_get_XmlText(ITaskDefinition *iface, BSTR *xml)
2807 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2808 HRESULT hr;
2809 IStream *stream;
2810 HGLOBAL hmem;
2811 void *p;
2813 TRACE("%p,%p\n", iface, xml);
2815 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16);
2816 if (!hmem) return E_OUTOFMEMORY;
2818 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2819 if (hr != S_OK)
2821 GlobalFree(hmem);
2822 return hr;
2825 hr = write_task_attributes(stream, &taskdef->ITaskDefinition_iface);
2826 if (hr != S_OK) goto failed;
2828 push_indent();
2830 hr = write_registration_info(stream, taskdef->reginfo);
2831 if (hr != S_OK) goto failed;
2833 hr = write_triggers(stream, taskdef->triggers);
2834 if (hr != S_OK) goto failed;
2836 hr = write_principal(stream, taskdef->principal);
2837 if (hr != S_OK) goto failed;
2839 hr = write_settings(stream, taskdef->taskset);
2840 if (hr != S_OK) goto failed;
2842 hr = write_actions(stream, taskdef->actions);
2843 if (hr != S_OK) goto failed;
2845 pop_indent();
2847 write_element_end(stream, Task);
2848 IStream_Write(stream, "\0\0", 2, NULL);
2850 p = GlobalLock(hmem);
2851 *xml = SysAllocString(p);
2852 GlobalUnlock(hmem);
2854 IStream_Release(stream);
2856 return *xml ? S_OK : E_OUTOFMEMORY;
2858 failed:
2859 IStream_Release(stream);
2860 return hr;
2863 static HRESULT read_text_value(IXmlReader *reader, WCHAR **value)
2865 HRESULT hr;
2866 XmlNodeType type;
2868 while (IXmlReader_Read(reader, &type) == S_OK)
2870 switch (type)
2872 case XmlNodeType_Text:
2873 hr = IXmlReader_GetValue(reader, (const WCHAR **)value, NULL);
2874 if (hr != S_OK) return hr;
2875 TRACE("%s\n", debugstr_w(*value));
2876 return S_OK;
2878 case XmlNodeType_Whitespace:
2879 case XmlNodeType_Comment:
2880 break;
2882 default:
2883 FIXME("unexpected node type %d\n", type);
2884 return E_FAIL;
2888 return E_FAIL;
2891 static HRESULT read_variantbool_value(IXmlReader *reader, VARIANT_BOOL *vbool)
2893 static const WCHAR trueW[] = {'t','r','u','e',0};
2894 static const WCHAR falseW[] = {'f','a','l','s','e',0};
2895 HRESULT hr;
2896 WCHAR *value;
2898 hr = read_text_value(reader, &value);
2899 if (hr != S_OK) return hr;
2901 if (!lstrcmpW(value, trueW))
2902 *vbool = VARIANT_TRUE;
2903 else if (!lstrcmpW(value, falseW))
2904 *vbool = VARIANT_FALSE;
2905 else
2907 WARN("unexpected bool value %s\n", debugstr_w(value));
2908 return SCHED_E_INVALIDVALUE;
2911 return S_OK;
2914 static HRESULT read_int_value(IXmlReader *reader, int *int_val)
2916 HRESULT hr;
2917 WCHAR *value;
2919 hr = read_text_value(reader, &value);
2920 if (hr != S_OK) return hr;
2922 *int_val = strtolW(value, NULL, 10);
2924 return S_OK;
2927 static HRESULT read_triggers(IXmlReader *reader, ITaskDefinition *taskdef)
2929 FIXME("stub\n");
2930 return S_OK;
2933 static HRESULT read_principal_attributes(IXmlReader *reader, IPrincipal *principal)
2935 HRESULT hr;
2936 const WCHAR *name;
2937 const WCHAR *value;
2939 hr = IXmlReader_MoveToFirstAttribute(reader);
2941 while (hr == S_OK)
2943 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2944 if (hr != S_OK) break;
2946 hr = IXmlReader_GetValue(reader, &value, NULL);
2947 if (hr != S_OK) break;
2949 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
2951 if (!lstrcmpW(name, id))
2952 IPrincipal_put_Id(principal, (BSTR)value);
2953 else
2954 FIXME("unhandled Principal attribute %s\n", debugstr_w(name));
2956 hr = IXmlReader_MoveToNextAttribute(reader);
2959 return S_OK;
2962 static HRESULT read_principal(IXmlReader *reader, IPrincipal *principal)
2964 HRESULT hr;
2965 XmlNodeType type;
2966 const WCHAR *name;
2967 WCHAR *value;
2969 if (IXmlReader_IsEmptyElement(reader))
2971 TRACE("Principal is empty\n");
2972 return S_OK;
2975 read_principal_attributes(reader, principal);
2977 while (IXmlReader_Read(reader, &type) == S_OK)
2979 switch (type)
2981 case XmlNodeType_EndElement:
2982 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2983 if (hr != S_OK) return hr;
2985 TRACE("/%s\n", debugstr_w(name));
2987 if (!lstrcmpW(name, principalW))
2988 return S_OK;
2990 break;
2992 case XmlNodeType_Element:
2993 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2994 if (hr != S_OK) return hr;
2996 TRACE("Element: %s\n", debugstr_w(name));
2998 if (!lstrcmpW(name, UserId))
3000 hr = read_text_value(reader, &value);
3001 if (hr == S_OK)
3002 IPrincipal_put_UserId(principal, value);
3004 else if (!lstrcmpW(name, LogonType))
3006 hr = read_text_value(reader, &value);
3007 if (hr == S_OK)
3009 TASK_LOGON_TYPE logon = TASK_LOGON_NONE;
3011 if (!lstrcmpW(value, InteractiveToken))
3012 logon = TASK_LOGON_INTERACTIVE_TOKEN;
3013 else
3014 FIXME("unhandled LogonType %s\n", debugstr_w(value));
3016 IPrincipal_put_LogonType(principal, logon);
3019 else if (!lstrcmpW(name, RunLevel))
3021 hr = read_text_value(reader, &value);
3022 if (hr == S_OK)
3024 TASK_RUNLEVEL_TYPE level = TASK_RUNLEVEL_LUA;
3026 if (!lstrcmpW(value, LeastPrivilege))
3027 level = TASK_RUNLEVEL_LUA;
3028 else
3029 FIXME("unhandled RunLevel %s\n", debugstr_w(value));
3031 IPrincipal_put_RunLevel(principal, level);
3034 else
3035 FIXME("unhandled Principal element %s\n", debugstr_w(name));
3037 break;
3039 case XmlNodeType_Whitespace:
3040 case XmlNodeType_Comment:
3041 break;
3043 default:
3044 FIXME("unhandled Principal node type %d\n", type);
3045 break;
3049 WARN("Principal was not terminated\n");
3050 return E_FAIL;
3053 static HRESULT read_principals(IXmlReader *reader, ITaskDefinition *taskdef)
3055 HRESULT hr;
3056 XmlNodeType type;
3057 const WCHAR *name;
3059 if (IXmlReader_IsEmptyElement(reader))
3061 TRACE("Principals is empty\n");
3062 return S_OK;
3065 while (IXmlReader_Read(reader, &type) == S_OK)
3067 switch (type)
3069 case XmlNodeType_EndElement:
3070 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3071 if (hr != S_OK) return hr;
3073 TRACE("/%s\n", debugstr_w(name));
3075 if (!lstrcmpW(name, Principals))
3076 return S_OK;
3078 break;
3080 case XmlNodeType_Element:
3081 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3082 if (hr != S_OK) return hr;
3084 TRACE("Element: %s\n", debugstr_w(name));
3086 if (!lstrcmpW(name, principalW))
3088 IPrincipal *principal;
3090 hr = ITaskDefinition_get_Principal(taskdef, &principal);
3091 if (hr != S_OK) return hr;
3092 hr = read_principal(reader, principal);
3093 IPrincipal_Release(principal);
3095 else
3096 FIXME("unhandled Principals element %s\n", debugstr_w(name));
3098 break;
3100 case XmlNodeType_Whitespace:
3101 case XmlNodeType_Comment:
3102 break;
3104 default:
3105 FIXME("unhandled Principals node type %d\n", type);
3106 break;
3110 WARN("Principals was not terminated\n");
3111 return E_FAIL;
3114 static HRESULT read_actions(IXmlReader *reader, ITaskDefinition *taskdef)
3116 FIXME("stub\n");
3117 return S_OK;
3120 static HRESULT read_idle_settings(IXmlReader *reader, ITaskSettings *taskset)
3122 FIXME("stub\n");
3123 return S_OK;
3126 static HRESULT read_settings(IXmlReader *reader, ITaskSettings *taskset)
3128 HRESULT hr;
3129 XmlNodeType type;
3130 const WCHAR *name;
3131 WCHAR *value;
3132 VARIANT_BOOL bool_val;
3133 int int_val;
3135 if (IXmlReader_IsEmptyElement(reader))
3137 TRACE("Settings is empty\n");
3138 return S_OK;
3141 while (IXmlReader_Read(reader, &type) == S_OK)
3143 switch (type)
3145 case XmlNodeType_EndElement:
3146 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3147 if (hr != S_OK) return hr;
3149 TRACE("/%s\n", debugstr_w(name));
3151 if (!lstrcmpW(name, Settings))
3152 return S_OK;
3154 break;
3156 case XmlNodeType_Element:
3157 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3158 if (hr != S_OK) return hr;
3160 TRACE("Element: %s\n", debugstr_w(name));
3162 if (!lstrcmpW(name, MultipleInstancesPolicy))
3164 hr = read_text_value(reader, &value);
3165 if (hr == S_OK)
3167 int_val = TASK_INSTANCES_IGNORE_NEW;
3169 if (!lstrcmpW(value, IgnoreNew))
3170 int_val = TASK_INSTANCES_IGNORE_NEW;
3171 else
3172 FIXME("unhandled MultipleInstancesPolicy %s\n", debugstr_w(value));
3174 ITaskSettings_put_MultipleInstances(taskset, int_val);
3177 else if (!lstrcmpW(name, DisallowStartIfOnBatteries))
3179 hr = read_variantbool_value(reader, &bool_val);
3180 if (hr != S_OK) return hr;
3181 ITaskSettings_put_DisallowStartIfOnBatteries(taskset, bool_val);
3183 else if (!lstrcmpW(name, AllowStartOnDemand))
3185 hr = read_variantbool_value(reader, &bool_val);
3186 if (hr != S_OK) return hr;
3187 ITaskSettings_put_AllowDemandStart(taskset, bool_val);
3189 else if (!lstrcmpW(name, StopIfGoingOnBatteries))
3191 hr = read_variantbool_value(reader, &bool_val);
3192 if (hr != S_OK) return hr;
3193 ITaskSettings_put_StopIfGoingOnBatteries(taskset, bool_val);
3195 else if (!lstrcmpW(name, AllowHardTerminate))
3197 hr = read_variantbool_value(reader, &bool_val);
3198 if (hr != S_OK) return hr;
3199 ITaskSettings_put_AllowHardTerminate(taskset, bool_val);
3201 else if (!lstrcmpW(name, StartWhenAvailable))
3203 hr = read_variantbool_value(reader, &bool_val);
3204 if (hr != S_OK) return hr;
3205 ITaskSettings_put_StartWhenAvailable(taskset, bool_val);
3207 else if (!lstrcmpW(name, RunOnlyIfNetworkAvailable))
3209 hr = read_variantbool_value(reader, &bool_val);
3210 if (hr != S_OK) return hr;
3211 ITaskSettings_put_RunOnlyIfNetworkAvailable(taskset, bool_val);
3213 else if (!lstrcmpW(name, Enabled))
3215 hr = read_variantbool_value(reader, &bool_val);
3216 if (hr != S_OK) return hr;
3217 ITaskSettings_put_Enabled(taskset, bool_val);
3219 else if (!lstrcmpW(name, Hidden))
3221 hr = read_variantbool_value(reader, &bool_val);
3222 if (hr != S_OK) return hr;
3223 ITaskSettings_put_Hidden(taskset, bool_val);
3225 else if (!lstrcmpW(name, RunOnlyIfIdle))
3227 hr = read_variantbool_value(reader, &bool_val);
3228 if (hr != S_OK) return hr;
3229 ITaskSettings_put_RunOnlyIfIdle(taskset, bool_val);
3231 else if (!lstrcmpW(name, WakeToRun))
3233 hr = read_variantbool_value(reader, &bool_val);
3234 if (hr != S_OK) return hr;
3235 ITaskSettings_put_WakeToRun(taskset, bool_val);
3237 else if (!lstrcmpW(name, ExecutionTimeLimit))
3239 hr = read_text_value(reader, &value);
3240 if (hr == S_OK)
3241 ITaskSettings_put_ExecutionTimeLimit(taskset, value);
3243 else if (!lstrcmpW(name, Priority))
3245 hr = read_int_value(reader, &int_val);
3246 if (hr == S_OK)
3247 ITaskSettings_put_Priority(taskset, int_val);
3249 else if (!lstrcmpW(name, IdleSettings))
3251 hr = read_idle_settings(reader, taskset);
3252 if (hr != S_OK) return hr;
3254 else
3255 FIXME("unhandled Settings element %s\n", debugstr_w(name));
3257 break;
3259 case XmlNodeType_Whitespace:
3260 case XmlNodeType_Comment:
3261 break;
3263 default:
3264 FIXME("unhandled Settings node type %d\n", type);
3265 break;
3269 WARN("Settings was not terminated\n");
3270 return SCHED_E_MALFORMEDXML;
3273 static HRESULT read_registration_info(IXmlReader *reader, IRegistrationInfo *info)
3275 HRESULT hr;
3276 XmlNodeType type;
3277 const WCHAR *name;
3278 WCHAR *value;
3280 if (IXmlReader_IsEmptyElement(reader))
3282 TRACE("RegistrationInfo is empty\n");
3283 return S_OK;
3286 while (IXmlReader_Read(reader, &type) == S_OK)
3288 switch (type)
3290 case XmlNodeType_EndElement:
3291 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3292 if (hr != S_OK) return hr;
3294 TRACE("/%s\n", debugstr_w(name));
3296 if (!lstrcmpW(name, RegistrationInfo))
3297 return S_OK;
3299 break;
3301 case XmlNodeType_Element:
3302 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3303 if (hr != S_OK) return hr;
3305 TRACE("Element: %s\n", debugstr_w(name));
3307 if (!lstrcmpW(name, Author))
3309 hr = read_text_value(reader, &value);
3310 if (hr == S_OK)
3311 IRegistrationInfo_put_Author(info, value);
3313 else if (!lstrcmpW(name, Description))
3315 hr = read_text_value(reader, &value);
3316 if (hr == S_OK)
3317 IRegistrationInfo_put_Description(info, value);
3319 else if (!lstrcmpW(name, Version))
3321 hr = read_text_value(reader, &value);
3322 if (hr == S_OK)
3323 IRegistrationInfo_put_Version(info, value);
3325 else if (!lstrcmpW(name, Date))
3327 hr = read_text_value(reader, &value);
3328 if (hr == S_OK)
3329 IRegistrationInfo_put_Date(info, value);
3331 else if (!lstrcmpW(name, Documentation))
3333 hr = read_text_value(reader, &value);
3334 if (hr == S_OK)
3335 IRegistrationInfo_put_Documentation(info, value);
3337 else if (!lstrcmpW(name, URI))
3339 hr = read_text_value(reader, &value);
3340 if (hr == S_OK)
3341 IRegistrationInfo_put_URI(info, value);
3343 else if (!lstrcmpW(name, Source))
3345 hr = read_text_value(reader, &value);
3346 if (hr == S_OK)
3347 IRegistrationInfo_put_Source(info, value);
3349 else
3350 FIXME("unhandled RegistrationInfo element %s\n", debugstr_w(name));
3352 break;
3354 case XmlNodeType_Whitespace:
3355 case XmlNodeType_Comment:
3356 break;
3358 default:
3359 FIXME("unhandled RegistrationInfo node type %d\n", type);
3360 break;
3364 WARN("RegistrationInfo was not terminated\n");
3365 return SCHED_E_MALFORMEDXML;
3368 static HRESULT read_task_attributes(IXmlReader *reader, ITaskDefinition *taskdef)
3370 HRESULT hr;
3371 ITaskSettings *taskset;
3372 const WCHAR *name;
3373 const WCHAR *value;
3374 BOOL xmlns_ok = FALSE;
3376 TRACE("\n");
3378 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3379 if (hr != S_OK) return hr;
3381 hr = IXmlReader_MoveToFirstAttribute(reader);
3383 while (hr == S_OK)
3385 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3386 if (hr != S_OK) break;
3388 hr = IXmlReader_GetValue(reader, &value, NULL);
3389 if (hr != S_OK) break;
3391 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
3393 if (!lstrcmpW(name, version))
3395 TASK_COMPATIBILITY compatibility = TASK_COMPATIBILITY_V2;
3397 if (!lstrcmpW(value, v1_0))
3398 compatibility = TASK_COMPATIBILITY_AT;
3399 else if (!lstrcmpW(value, v1_1))
3400 compatibility = TASK_COMPATIBILITY_V1;
3401 else if (!lstrcmpW(value, v1_2))
3402 compatibility = TASK_COMPATIBILITY_V2;
3403 else if (!lstrcmpW(value, v1_3))
3404 compatibility = TASK_COMPATIBILITY_V2_1;
3405 else
3406 FIXME("unknown version %s\n", debugstr_w(value));
3408 ITaskSettings_put_Compatibility(taskset, compatibility);
3410 else if (!lstrcmpW(name, xmlns))
3412 if (lstrcmpW(value, task_ns))
3414 FIXME("unknown namespace %s\n", debugstr_w(value));
3415 break;
3417 xmlns_ok = TRUE;
3419 else
3420 FIXME("unhandled Task attribute %s\n", debugstr_w(name));
3422 hr = IXmlReader_MoveToNextAttribute(reader);
3425 ITaskSettings_Release(taskset);
3426 return xmlns_ok ? S_OK : SCHED_E_NAMESPACE;
3429 static HRESULT read_task(IXmlReader *reader, ITaskDefinition *taskdef)
3431 HRESULT hr;
3432 XmlNodeType type;
3433 const WCHAR *name;
3435 if (IXmlReader_IsEmptyElement(reader))
3437 TRACE("Task is empty\n");
3438 return S_OK;
3441 while (IXmlReader_Read(reader, &type) == S_OK)
3443 switch (type)
3445 case XmlNodeType_EndElement:
3446 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3447 if (hr != S_OK) return hr;
3449 TRACE("/%s\n", debugstr_w(name));
3451 if (!lstrcmpW(name, Task))
3452 return S_OK;
3454 break;
3456 case XmlNodeType_Element:
3457 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3458 if (hr != S_OK) return hr;
3460 TRACE("Element: %s\n", debugstr_w(name));
3462 if (!lstrcmpW(name, RegistrationInfo))
3464 IRegistrationInfo *info;
3466 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &info);
3467 if (hr != S_OK) return hr;
3468 hr = read_registration_info(reader, info);
3469 IRegistrationInfo_Release(info);
3471 else if (!lstrcmpW(name, Settings))
3473 ITaskSettings *taskset;
3475 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3476 if (hr != S_OK) return hr;
3477 hr = read_settings(reader, taskset);
3478 ITaskSettings_Release(taskset);
3480 else if (!lstrcmpW(name, Triggers))
3481 hr = read_triggers(reader, taskdef);
3482 else if (!lstrcmpW(name, Principals))
3483 hr = read_principals(reader, taskdef);
3484 else if (!lstrcmpW(name, actionsW))
3485 hr = read_actions(reader, taskdef);
3486 else
3487 FIXME("unhandled Task element %s\n", debugstr_w(name));
3489 if (hr != S_OK) return hr;
3490 break;
3492 case XmlNodeType_Comment:
3493 case XmlNodeType_Whitespace:
3494 break;
3496 default:
3497 FIXME("unhandled Task node type %d\n", type);
3498 break;
3502 WARN("Task was not terminated\n");
3503 return SCHED_E_MALFORMEDXML;
3506 static HRESULT read_xml(IXmlReader *reader, ITaskDefinition *taskdef)
3508 HRESULT hr;
3509 XmlNodeType type;
3510 const WCHAR *name;
3512 while (IXmlReader_Read(reader, &type) == S_OK)
3514 switch (type)
3516 case XmlNodeType_XmlDeclaration:
3517 TRACE("XmlDeclaration\n");
3518 break;
3520 case XmlNodeType_Element:
3521 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3522 if (hr != S_OK) return hr;
3524 TRACE("Element: %s\n", debugstr_w(name));
3526 if (!lstrcmpW(name, Task))
3528 hr = read_task_attributes(reader, taskdef);
3529 if (hr != S_OK) return hr;
3531 return read_task(reader, taskdef);
3533 else
3534 FIXME("unhandled XML element %s\n", debugstr_w(name));
3536 break;
3538 case XmlNodeType_Comment:
3539 case XmlNodeType_Whitespace:
3540 break;
3542 default:
3543 FIXME("unhandled XML node type %d\n", type);
3544 break;
3548 WARN("Task definition was not found\n");
3549 return SCHED_E_MALFORMEDXML;
3552 static HRESULT WINAPI TaskDefinition_put_XmlText(ITaskDefinition *iface, BSTR xml)
3554 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
3555 HRESULT hr;
3556 IStream *stream;
3557 IXmlReader *reader;
3558 HGLOBAL hmem;
3559 void *buf;
3561 TRACE("%p,%s\n", iface, debugstr_w(xml));
3563 if (!xml) return E_INVALIDARG;
3565 hmem = GlobalAlloc(0, lstrlenW(xml) * sizeof(WCHAR));
3566 if (!hmem) return E_OUTOFMEMORY;
3568 buf = GlobalLock(hmem);
3569 memcpy(buf, xml, lstrlenW(xml) * sizeof(WCHAR));
3570 GlobalUnlock(hmem);
3572 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
3573 if (hr != S_OK)
3575 GlobalFree(hmem);
3576 return hr;
3579 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
3580 if (hr != S_OK)
3582 IStream_Release(stream);
3583 return hr;
3586 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
3587 if (hr == S_OK)
3589 if (taskdef->reginfo)
3591 IRegistrationInfo_Release(taskdef->reginfo);
3592 taskdef->reginfo = NULL;
3594 if (taskdef->taskset)
3596 ITaskSettings_Release(taskdef->taskset);
3597 taskdef->taskset = NULL;
3599 if (taskdef->triggers)
3601 ITriggerCollection_Release(taskdef->triggers);
3602 taskdef->triggers = NULL;
3604 if (taskdef->principal)
3606 IPrincipal_Release(taskdef->principal);
3607 taskdef->principal = NULL;
3609 if (taskdef->actions)
3611 IActionCollection_Release(taskdef->actions);
3612 taskdef->actions = NULL;
3615 hr = read_xml(reader, iface);
3618 IXmlReader_Release(reader);
3619 IStream_Release(stream);
3621 return hr;
3624 static const ITaskDefinitionVtbl TaskDefinition_vtbl =
3626 TaskDefinition_QueryInterface,
3627 TaskDefinition_AddRef,
3628 TaskDefinition_Release,
3629 TaskDefinition_GetTypeInfoCount,
3630 TaskDefinition_GetTypeInfo,
3631 TaskDefinition_GetIDsOfNames,
3632 TaskDefinition_Invoke,
3633 TaskDefinition_get_RegistrationInfo,
3634 TaskDefinition_put_RegistrationInfo,
3635 TaskDefinition_get_Triggers,
3636 TaskDefinition_put_Triggers,
3637 TaskDefinition_get_Settings,
3638 TaskDefinition_put_Settings,
3639 TaskDefinition_get_Data,
3640 TaskDefinition_put_Data,
3641 TaskDefinition_get_Principal,
3642 TaskDefinition_put_Principal,
3643 TaskDefinition_get_Actions,
3644 TaskDefinition_put_Actions,
3645 TaskDefinition_get_XmlText,
3646 TaskDefinition_put_XmlText
3649 HRESULT TaskDefinition_create(ITaskDefinition **obj)
3651 TaskDefinition *taskdef;
3653 taskdef = heap_alloc_zero(sizeof(*taskdef));
3654 if (!taskdef) return E_OUTOFMEMORY;
3656 taskdef->ITaskDefinition_iface.lpVtbl = &TaskDefinition_vtbl;
3657 taskdef->ref = 1;
3658 *obj = &taskdef->ITaskDefinition_iface;
3660 TRACE("created %p\n", *obj);
3662 return S_OK;
3665 typedef struct
3667 ITaskService ITaskService_iface;
3668 LONG ref;
3669 BOOL connected;
3670 DWORD version;
3671 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3672 } TaskService;
3674 static inline TaskService *impl_from_ITaskService(ITaskService *iface)
3676 return CONTAINING_RECORD(iface, TaskService, ITaskService_iface);
3679 static ULONG WINAPI TaskService_AddRef(ITaskService *iface)
3681 TaskService *task_svc = impl_from_ITaskService(iface);
3682 return InterlockedIncrement(&task_svc->ref);
3685 static ULONG WINAPI TaskService_Release(ITaskService *iface)
3687 TaskService *task_svc = impl_from_ITaskService(iface);
3688 LONG ref = InterlockedDecrement(&task_svc->ref);
3690 if (!ref)
3692 TRACE("destroying %p\n", iface);
3693 heap_free(task_svc);
3696 return ref;
3699 static HRESULT WINAPI TaskService_QueryInterface(ITaskService *iface, REFIID riid, void **obj)
3701 if (!riid || !obj) return E_INVALIDARG;
3703 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
3705 if (IsEqualGUID(riid, &IID_ITaskService) ||
3706 IsEqualGUID(riid, &IID_IDispatch) ||
3707 IsEqualGUID(riid, &IID_IUnknown))
3709 ITaskService_AddRef(iface);
3710 *obj = iface;
3711 return S_OK;
3714 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
3715 *obj = NULL;
3716 return E_NOINTERFACE;
3719 static HRESULT WINAPI TaskService_GetTypeInfoCount(ITaskService *iface, UINT *count)
3721 FIXME("%p,%p: stub\n", iface, count);
3722 return E_NOTIMPL;
3725 static HRESULT WINAPI TaskService_GetTypeInfo(ITaskService *iface, UINT index, LCID lcid, ITypeInfo **info)
3727 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
3728 return E_NOTIMPL;
3731 static HRESULT WINAPI TaskService_GetIDsOfNames(ITaskService *iface, REFIID riid, LPOLESTR *names,
3732 UINT count, LCID lcid, DISPID *dispid)
3734 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
3735 return E_NOTIMPL;
3738 static HRESULT WINAPI TaskService_Invoke(ITaskService *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
3739 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
3741 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
3742 params, result, excepinfo, argerr);
3743 return E_NOTIMPL;
3746 static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITaskFolder **folder)
3748 TaskService *task_svc = impl_from_ITaskService(iface);
3750 TRACE("%p,%s,%p\n", iface, debugstr_w(path), folder);
3752 if (!folder) return E_POINTER;
3754 if (!task_svc->connected)
3755 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3757 return TaskFolder_create(path, NULL, folder, FALSE);
3760 static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks)
3762 FIXME("%p,%x,%p: stub\n", iface, flags, tasks);
3763 return E_NOTIMPL;
3766 static HRESULT WINAPI TaskService_NewTask(ITaskService *iface, DWORD flags, ITaskDefinition **definition)
3768 TRACE("%p,%x,%p\n", iface, flags, definition);
3770 if (!definition) return E_POINTER;
3772 if (flags)
3773 FIXME("unsupported flags %x\n", flags);
3775 return TaskDefinition_create(definition);
3778 static inline BOOL is_variant_null(const VARIANT *var)
3780 return V_VT(var) == VT_EMPTY || V_VT(var) == VT_NULL ||
3781 (V_VT(var) == VT_BSTR && (V_BSTR(var) == NULL || !*V_BSTR(var)));
3784 static HRESULT start_schedsvc(void)
3786 static const WCHAR scheduleW[] = { 'S','c','h','e','d','u','l','e',0 };
3787 SC_HANDLE scm, service;
3788 SERVICE_STATUS_PROCESS status;
3789 ULONGLONG start_time;
3790 HRESULT hr = SCHED_E_SERVICE_NOT_RUNNING;
3792 TRACE("Trying to start %s service\n", debugstr_w(scheduleW));
3794 scm = OpenSCManagerW(NULL, NULL, 0);
3795 if (!scm) return SCHED_E_SERVICE_NOT_INSTALLED;
3797 service = OpenServiceW(scm, scheduleW, SERVICE_START | SERVICE_QUERY_STATUS);
3798 if (service)
3800 if (StartServiceW(service, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
3802 start_time = GetTickCount64();
3805 DWORD dummy;
3807 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(status), &dummy))
3809 WARN("failed to query scheduler status (%u)\n", GetLastError());
3810 break;
3813 if (status.dwCurrentState == SERVICE_RUNNING)
3815 hr = S_OK;
3816 break;
3819 if (GetTickCount64() - start_time > 30000) break;
3820 Sleep(1000);
3822 } while (status.dwCurrentState == SERVICE_START_PENDING);
3824 if (status.dwCurrentState != SERVICE_RUNNING)
3825 WARN("scheduler failed to start %u\n", status.dwCurrentState);
3827 else
3828 WARN("failed to start scheduler service (%u)\n", GetLastError());
3830 CloseServiceHandle(service);
3832 else
3833 WARN("failed to open scheduler service (%u)\n", GetLastError());
3835 CloseServiceHandle(scm);
3836 return hr;
3839 static HRESULT WINAPI TaskService_Connect(ITaskService *iface, VARIANT server, VARIANT user, VARIANT domain, VARIANT password)
3841 static WCHAR ncalrpc[] = { 'n','c','a','l','r','p','c',0 };
3842 TaskService *task_svc = impl_from_ITaskService(iface);
3843 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3844 DWORD len;
3845 HRESULT hr;
3846 RPC_WSTR binding_str;
3847 extern handle_t rpc_handle;
3849 TRACE("%p,%s,%s,%s,%s\n", iface, debugstr_variant(&server), debugstr_variant(&user),
3850 debugstr_variant(&domain), debugstr_variant(&password));
3852 if (!is_variant_null(&user) || !is_variant_null(&domain) || !is_variant_null(&password))
3853 FIXME("user/domain/password are ignored\n");
3855 len = ARRAY_SIZE(comp_name);
3856 if (!GetComputerNameW(comp_name, &len))
3857 return HRESULT_FROM_WIN32(GetLastError());
3859 if (!is_variant_null(&server))
3861 const WCHAR *server_name;
3863 if (V_VT(&server) != VT_BSTR)
3865 FIXME("server variant type %d is not supported\n", V_VT(&server));
3866 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3869 /* skip UNC prefix if any */
3870 server_name = V_BSTR(&server);
3871 if (server_name[0] == '\\' && server_name[1] == '\\')
3872 server_name += 2;
3874 if (strcmpiW(server_name, comp_name))
3876 FIXME("connection to remote server %s is not supported\n", debugstr_w(V_BSTR(&server)));
3877 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3881 hr = start_schedsvc();
3882 if (hr != S_OK) return hr;
3884 hr = RpcStringBindingComposeW(NULL, ncalrpc, NULL, NULL, NULL, &binding_str);
3885 if (hr != RPC_S_OK) return hr;
3886 hr = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
3887 RpcStringFreeW(&binding_str);
3888 if (hr != RPC_S_OK) return hr;
3890 /* Make sure that the connection works */
3891 hr = SchRpcHighestVersion(&task_svc->version);
3892 if (hr != S_OK) return hr;
3894 TRACE("server version %#x\n", task_svc->version);
3896 strcpyW(task_svc->comp_name, comp_name);
3897 task_svc->connected = TRUE;
3899 return S_OK;
3902 static HRESULT WINAPI TaskService_get_Connected(ITaskService *iface, VARIANT_BOOL *connected)
3904 TaskService *task_svc = impl_from_ITaskService(iface);
3906 TRACE("%p,%p\n", iface, connected);
3908 if (!connected) return E_POINTER;
3910 *connected = task_svc->connected ? VARIANT_TRUE : VARIANT_FALSE;
3912 return S_OK;
3915 static HRESULT WINAPI TaskService_get_TargetServer(ITaskService *iface, BSTR *server)
3917 TaskService *task_svc = impl_from_ITaskService(iface);
3919 TRACE("%p,%p\n", iface, server);
3921 if (!server) return E_POINTER;
3923 if (!task_svc->connected)
3924 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3926 *server = SysAllocString(task_svc->comp_name);
3927 if (!*server) return E_OUTOFMEMORY;
3929 return S_OK;
3932 static HRESULT WINAPI TaskService_get_ConnectedUser(ITaskService *iface, BSTR *user)
3934 FIXME("%p,%p: stub\n", iface, user);
3935 return E_NOTIMPL;
3938 static HRESULT WINAPI TaskService_get_ConnectedDomain(ITaskService *iface, BSTR *domain)
3940 FIXME("%p,%p: stub\n", iface, domain);
3941 return E_NOTIMPL;
3944 static HRESULT WINAPI TaskService_get_HighestVersion(ITaskService *iface, DWORD *version)
3946 TaskService *task_svc = impl_from_ITaskService(iface);
3948 TRACE("%p,%p\n", iface, version);
3950 if (!version) return E_POINTER;
3952 if (!task_svc->connected)
3953 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3955 *version = task_svc->version;
3957 return S_OK;
3960 static const ITaskServiceVtbl TaskService_vtbl =
3962 TaskService_QueryInterface,
3963 TaskService_AddRef,
3964 TaskService_Release,
3965 TaskService_GetTypeInfoCount,
3966 TaskService_GetTypeInfo,
3967 TaskService_GetIDsOfNames,
3968 TaskService_Invoke,
3969 TaskService_GetFolder,
3970 TaskService_GetRunningTasks,
3971 TaskService_NewTask,
3972 TaskService_Connect,
3973 TaskService_get_Connected,
3974 TaskService_get_TargetServer,
3975 TaskService_get_ConnectedUser,
3976 TaskService_get_ConnectedDomain,
3977 TaskService_get_HighestVersion
3980 HRESULT TaskService_create(void **obj)
3982 TaskService *task_svc;
3984 task_svc = heap_alloc(sizeof(*task_svc));
3985 if (!task_svc) return E_OUTOFMEMORY;
3987 task_svc->ITaskService_iface.lpVtbl = &TaskService_vtbl;
3988 task_svc->ref = 1;
3989 task_svc->connected = FALSE;
3990 *obj = &task_svc->ITaskService_iface;
3992 TRACE("created %p\n", *obj);
3994 return S_OK;
3997 void __RPC_FAR *__RPC_USER MIDL_user_allocate(SIZE_T n)
3999 return HeapAlloc(GetProcessHeap(), 0, n);
4002 void __RPC_USER MIDL_user_free(void __RPC_FAR *p)
4004 HeapFree(GetProcessHeap(), 0, p);