makefiles: Explicitly create destination dirs when installing symlinks.
[wine/zf.git] / dlls / taskschd / task.c
blob8d81a18b3f51132e1619a10c870d66996d858862
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/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(taskschd);
37 typedef struct {
38 IDailyTrigger IDailyTrigger_iface;
39 LONG ref;
40 short interval;
41 WCHAR *start_boundary;
42 BOOL enabled;
43 } DailyTrigger;
45 static inline DailyTrigger *impl_from_IDailyTrigger(IDailyTrigger *iface)
47 return CONTAINING_RECORD(iface, DailyTrigger, IDailyTrigger_iface);
50 static HRESULT WINAPI DailyTrigger_QueryInterface(IDailyTrigger *iface, REFIID riid, void **ppv)
52 DailyTrigger *This = impl_from_IDailyTrigger(iface);
54 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
56 if(IsEqualGUID(&IID_IUnknown, riid) ||
57 IsEqualGUID(&IID_IDispatch, riid) ||
58 IsEqualGUID(&IID_ITrigger, riid) ||
59 IsEqualGUID(&IID_IDailyTrigger, riid))
61 *ppv = &This->IDailyTrigger_iface;
63 else
65 FIXME("unsupported riid %s\n", debugstr_guid(riid));
66 *ppv = NULL;
67 return E_NOINTERFACE;
70 IUnknown_AddRef((IUnknown*)*ppv);
71 return S_OK;
74 static ULONG WINAPI DailyTrigger_AddRef(IDailyTrigger *iface)
76 DailyTrigger *This = impl_from_IDailyTrigger(iface);
77 LONG ref = InterlockedIncrement(&This->ref);
79 TRACE("(%p) ref=%d\n", This, ref);
81 return ref;
84 static ULONG WINAPI DailyTrigger_Release(IDailyTrigger *iface)
86 DailyTrigger *This = impl_from_IDailyTrigger(iface);
87 LONG ref = InterlockedDecrement(&This->ref);
89 TRACE("(%p) ref=%d\n", This, ref);
91 if(!ref)
93 TRACE("destroying %p\n", iface);
94 heap_free(This->start_boundary);
95 heap_free(This);
98 return ref;
101 static HRESULT WINAPI DailyTrigger_GetTypeInfoCount(IDailyTrigger *iface, UINT *count)
103 DailyTrigger *This = impl_from_IDailyTrigger(iface);
104 FIXME("(%p)->(%p)\n", This, count);
105 return E_NOTIMPL;
108 static HRESULT WINAPI DailyTrigger_GetTypeInfo(IDailyTrigger *iface, UINT index, LCID lcid, ITypeInfo **info)
110 DailyTrigger *This = impl_from_IDailyTrigger(iface);
111 FIXME("(%p)->(%u %u %p)\n", This, index, lcid, info);
112 return E_NOTIMPL;
115 static HRESULT WINAPI DailyTrigger_GetIDsOfNames(IDailyTrigger *iface, REFIID riid, LPOLESTR *names,
116 UINT count, LCID lcid, DISPID *dispid)
118 DailyTrigger *This = impl_from_IDailyTrigger(iface);
119 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), names, count, lcid, dispid);
120 return E_NOTIMPL;
123 static HRESULT WINAPI DailyTrigger_Invoke(IDailyTrigger *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
124 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
126 DailyTrigger *This = impl_from_IDailyTrigger(iface);
127 FIXME("(%p)->(%d %s %x %x %p %p %p %p)\n", This, dispid, debugstr_guid(riid), lcid, flags,
128 params, result, excepinfo, argerr);
129 return E_NOTIMPL;
132 static HRESULT WINAPI DailyTrigger_get_Type(IDailyTrigger *iface, TASK_TRIGGER_TYPE2 *type)
134 DailyTrigger *This = impl_from_IDailyTrigger(iface);
135 FIXME("(%p)->(%p)\n", This, type);
136 return E_NOTIMPL;
139 static HRESULT WINAPI DailyTrigger_get_Id(IDailyTrigger *iface, BSTR *id)
141 DailyTrigger *This = impl_from_IDailyTrigger(iface);
142 FIXME("(%p)->(%p)\n", This, id);
143 return E_NOTIMPL;
146 static HRESULT WINAPI DailyTrigger_put_Id(IDailyTrigger *iface, BSTR id)
148 DailyTrigger *This = impl_from_IDailyTrigger(iface);
149 FIXME("(%p)->(%s)\n", This, debugstr_w(id));
150 return E_NOTIMPL;
153 static HRESULT WINAPI DailyTrigger_get_Repetition(IDailyTrigger *iface, IRepetitionPattern **repeat)
155 DailyTrigger *This = impl_from_IDailyTrigger(iface);
156 FIXME("(%p)->(%p)\n", This, repeat);
157 return E_NOTIMPL;
160 static HRESULT WINAPI DailyTrigger_put_Repetition(IDailyTrigger *iface, IRepetitionPattern *repeat)
162 DailyTrigger *This = impl_from_IDailyTrigger(iface);
163 FIXME("(%p)->(%p)\n", This, repeat);
164 return E_NOTIMPL;
167 static HRESULT WINAPI DailyTrigger_get_ExecutionTimeLimit(IDailyTrigger *iface, BSTR *limit)
169 DailyTrigger *This = impl_from_IDailyTrigger(iface);
170 FIXME("(%p)->(%p)\n", This, limit);
171 return E_NOTIMPL;
174 static HRESULT WINAPI DailyTrigger_put_ExecutionTimeLimit(IDailyTrigger *iface, BSTR limit)
176 DailyTrigger *This = impl_from_IDailyTrigger(iface);
177 FIXME("(%p)->(%s)\n", This, debugstr_w(limit));
178 return E_NOTIMPL;
181 static HRESULT WINAPI DailyTrigger_get_StartBoundary(IDailyTrigger *iface, BSTR *start)
183 DailyTrigger *This = impl_from_IDailyTrigger(iface);
185 TRACE("(%p)->(%p)\n", This, start);
187 if (!start) return E_POINTER;
189 if (!This->start_boundary) *start = NULL;
190 else if (!(*start = SysAllocString(This->start_boundary))) return E_OUTOFMEMORY;
192 return S_OK;
195 static HRESULT WINAPI DailyTrigger_put_StartBoundary(IDailyTrigger *iface, BSTR start)
197 DailyTrigger *This = impl_from_IDailyTrigger(iface);
198 WCHAR *str = NULL;
200 TRACE("(%p)->(%s)\n", This, debugstr_w(start));
202 if (start && !(str = heap_strdupW(start))) return E_OUTOFMEMORY;
203 heap_free(This->start_boundary);
204 This->start_boundary = str;
206 return S_OK;
209 static HRESULT WINAPI DailyTrigger_get_EndBoundary(IDailyTrigger *iface, BSTR *end)
211 DailyTrigger *This = impl_from_IDailyTrigger(iface);
212 FIXME("(%p)->(%p)\n", This, end);
213 return E_NOTIMPL;
216 static HRESULT WINAPI DailyTrigger_put_EndBoundary(IDailyTrigger *iface, BSTR end)
218 DailyTrigger *This = impl_from_IDailyTrigger(iface);
219 FIXME("(%p)->(%s)\n", This, debugstr_w(end));
220 return E_NOTIMPL;
223 static HRESULT WINAPI DailyTrigger_get_Enabled(IDailyTrigger *iface, VARIANT_BOOL *enabled)
225 DailyTrigger *This = impl_from_IDailyTrigger(iface);
227 TRACE("(%p)->(%p)\n", This, enabled);
229 if (!enabled) return E_POINTER;
231 *enabled = This->enabled ? VARIANT_TRUE : VARIANT_FALSE;
232 return S_OK;
235 static HRESULT WINAPI DailyTrigger_put_Enabled(IDailyTrigger *iface, VARIANT_BOOL enabled)
237 DailyTrigger *This = impl_from_IDailyTrigger(iface);
239 TRACE("(%p)->(%x)\n", This, enabled);
241 This->enabled = !!enabled;
242 return S_OK;
245 static HRESULT WINAPI DailyTrigger_get_DaysInterval(IDailyTrigger *iface, short *days)
247 DailyTrigger *This = impl_from_IDailyTrigger(iface);
249 TRACE("(%p)->(%p)\n", This, days);
251 *days = This->interval;
252 return S_OK;
255 static HRESULT WINAPI DailyTrigger_put_DaysInterval(IDailyTrigger *iface, short days)
257 DailyTrigger *This = impl_from_IDailyTrigger(iface);
259 TRACE("(%p)->(%d)\n", This, days);
261 if(days <= 0)
262 return E_INVALIDARG;
264 This->interval = days;
265 return S_OK;
268 static HRESULT WINAPI DailyTrigger_get_RandomDelay(IDailyTrigger *iface, BSTR *pRandomDelay)
270 DailyTrigger *This = impl_from_IDailyTrigger(iface);
271 FIXME("(%p)->(%p)\n", This, pRandomDelay);
272 return E_NOTIMPL;
275 static HRESULT WINAPI DailyTrigger_put_RandomDelay(IDailyTrigger *iface, BSTR randomDelay)
277 DailyTrigger *This = impl_from_IDailyTrigger(iface);
278 FIXME("(%p)->(%s)\n", This, debugstr_w(randomDelay));
279 return E_NOTIMPL;
282 static const IDailyTriggerVtbl DailyTrigger_vtbl = {
283 DailyTrigger_QueryInterface,
284 DailyTrigger_AddRef,
285 DailyTrigger_Release,
286 DailyTrigger_GetTypeInfoCount,
287 DailyTrigger_GetTypeInfo,
288 DailyTrigger_GetIDsOfNames,
289 DailyTrigger_Invoke,
290 DailyTrigger_get_Type,
291 DailyTrigger_get_Id,
292 DailyTrigger_put_Id,
293 DailyTrigger_get_Repetition,
294 DailyTrigger_put_Repetition,
295 DailyTrigger_get_ExecutionTimeLimit,
296 DailyTrigger_put_ExecutionTimeLimit,
297 DailyTrigger_get_StartBoundary,
298 DailyTrigger_put_StartBoundary,
299 DailyTrigger_get_EndBoundary,
300 DailyTrigger_put_EndBoundary,
301 DailyTrigger_get_Enabled,
302 DailyTrigger_put_Enabled,
303 DailyTrigger_get_DaysInterval,
304 DailyTrigger_put_DaysInterval,
305 DailyTrigger_get_RandomDelay,
306 DailyTrigger_put_RandomDelay
309 static HRESULT DailyTrigger_create(ITrigger **trigger)
311 DailyTrigger *daily_trigger;
313 daily_trigger = heap_alloc(sizeof(*daily_trigger));
314 if (!daily_trigger)
315 return E_OUTOFMEMORY;
317 daily_trigger->IDailyTrigger_iface.lpVtbl = &DailyTrigger_vtbl;
318 daily_trigger->ref = 1;
319 daily_trigger->interval = 1;
320 daily_trigger->start_boundary = NULL;
321 daily_trigger->enabled = TRUE;
323 *trigger = (ITrigger*)&daily_trigger->IDailyTrigger_iface;
324 return S_OK;
327 typedef struct
329 ITriggerCollection ITriggerCollection_iface;
330 LONG ref;
331 } trigger_collection;
333 static inline trigger_collection *impl_from_ITriggerCollection(ITriggerCollection *iface)
335 return CONTAINING_RECORD(iface, trigger_collection, ITriggerCollection_iface);
338 static HRESULT WINAPI TriggerCollection_QueryInterface(ITriggerCollection *iface, REFIID riid, void **ppv)
340 trigger_collection *This = impl_from_ITriggerCollection(iface);
342 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
344 if(IsEqualGUID(&IID_IUnknown, riid) ||
345 IsEqualGUID(&IID_IDispatch, riid) ||
346 IsEqualGUID(&IID_ITriggerCollection, riid)) {
347 *ppv = &This->ITriggerCollection_iface;
348 }else {
349 FIXME("unimplemented interface %s\n", debugstr_guid(riid));
350 *ppv = NULL;
351 return E_NOINTERFACE;
354 IUnknown_AddRef((IUnknown*)*ppv);
355 return S_OK;
358 static ULONG WINAPI TriggerCollection_AddRef(ITriggerCollection *iface)
360 trigger_collection *This = impl_from_ITriggerCollection(iface);
361 LONG ref = InterlockedIncrement(&This->ref);
363 TRACE("(%p) ref=%d\n", This, ref);
365 return ref;
368 static ULONG WINAPI TriggerCollection_Release(ITriggerCollection *iface)
370 trigger_collection *This = impl_from_ITriggerCollection(iface);
371 LONG ref = InterlockedDecrement(&This->ref);
373 TRACE("(%p) ref=%d\n", This, ref);
375 if(!ref)
376 heap_free(This);
378 return ref;
381 static HRESULT WINAPI TriggerCollection_GetTypeInfoCount(ITriggerCollection *iface, UINT *count)
383 trigger_collection *This = impl_from_ITriggerCollection(iface);
384 FIXME("(%p)->(%p)\n", This, count);
385 return E_NOTIMPL;
388 static HRESULT WINAPI TriggerCollection_GetTypeInfo(ITriggerCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
390 trigger_collection *This = impl_from_ITriggerCollection(iface);
391 FIXME("(%p)->(%u %u %p)\n", This, index, lcid, info);
392 return E_NOTIMPL;
395 static HRESULT WINAPI TriggerCollection_GetIDsOfNames(ITriggerCollection *iface, REFIID riid, LPOLESTR *names,
396 UINT count, LCID lcid, DISPID *dispid)
398 trigger_collection *This = impl_from_ITriggerCollection(iface);
399 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), names, count, lcid, dispid);
400 return E_NOTIMPL;
403 static HRESULT WINAPI TriggerCollection_Invoke(ITriggerCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
404 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
406 trigger_collection *This = impl_from_ITriggerCollection(iface);
407 FIXME("(%p)->(%d %s %x %x %p %p %p %p)\n", This, dispid, debugstr_guid(riid), lcid, flags,
408 params, result, excepinfo, argerr);
409 return E_NOTIMPL;
412 static HRESULT WINAPI TriggerCollection_get_Count(ITriggerCollection *iface, LONG *count)
414 trigger_collection *This = impl_from_ITriggerCollection(iface);
415 FIXME("(%p)->(%p)\n", This, count);
416 return E_NOTIMPL;
419 static HRESULT WINAPI TriggerCollection_get_Item(ITriggerCollection *iface, LONG index, ITrigger **trigger)
421 trigger_collection *This = impl_from_ITriggerCollection(iface);
422 FIXME("(%p)->(%d %p)\n", This, index, trigger);
423 return E_NOTIMPL;
426 static HRESULT WINAPI TriggerCollection_get__NewEnum(ITriggerCollection *iface, IUnknown **penum)
428 trigger_collection *This = impl_from_ITriggerCollection(iface);
429 FIXME("(%p)->(%p)\n", This, penum);
430 return E_NOTIMPL;
433 static HRESULT WINAPI TriggerCollection_Create(ITriggerCollection *iface, TASK_TRIGGER_TYPE2 type, ITrigger **trigger)
435 trigger_collection *This = impl_from_ITriggerCollection(iface);
437 TRACE("(%p)->(%d %p)\n", This, type, trigger);
439 switch(type) {
440 case TASK_TRIGGER_DAILY:
441 return DailyTrigger_create(trigger);
442 default:
443 FIXME("Unimplemented type %d\n", type);
444 return E_NOTIMPL;
447 return S_OK;
450 static HRESULT WINAPI TriggerCollection_Remove(ITriggerCollection *iface, VARIANT index)
452 trigger_collection *This = impl_from_ITriggerCollection(iface);
453 FIXME("(%p)->(%s)\n", This, debugstr_variant(&index));
454 return E_NOTIMPL;
457 static HRESULT WINAPI TriggerCollection_Clear(ITriggerCollection *iface)
459 trigger_collection *This = impl_from_ITriggerCollection(iface);
460 FIXME("(%p)\n", This);
461 return E_NOTIMPL;
464 static const ITriggerCollectionVtbl TriggerCollection_vtbl = {
465 TriggerCollection_QueryInterface,
466 TriggerCollection_AddRef,
467 TriggerCollection_Release,
468 TriggerCollection_GetTypeInfoCount,
469 TriggerCollection_GetTypeInfo,
470 TriggerCollection_GetIDsOfNames,
471 TriggerCollection_Invoke,
472 TriggerCollection_get_Count,
473 TriggerCollection_get_Item,
474 TriggerCollection_get__NewEnum,
475 TriggerCollection_Create,
476 TriggerCollection_Remove,
477 TriggerCollection_Clear
480 typedef struct
482 IRegistrationInfo IRegistrationInfo_iface;
483 LONG ref;
484 WCHAR *description, *author, *version, *date, *documentation, *uri, *source;
485 } registration_info;
487 static inline registration_info *impl_from_IRegistrationInfo(IRegistrationInfo *iface)
489 return CONTAINING_RECORD(iface, registration_info, IRegistrationInfo_iface);
492 static ULONG WINAPI RegistrationInfo_AddRef(IRegistrationInfo *iface)
494 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
495 return InterlockedIncrement(&reginfo->ref);
498 static ULONG WINAPI RegistrationInfo_Release(IRegistrationInfo *iface)
500 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
501 LONG ref = InterlockedDecrement(&reginfo->ref);
503 if (!ref)
505 TRACE("destroying %p\n", iface);
506 heap_free(reginfo->description);
507 heap_free(reginfo->author);
508 heap_free(reginfo->version);
509 heap_free(reginfo->date);
510 heap_free(reginfo->documentation);
511 heap_free(reginfo->uri);
512 heap_free(reginfo->source);
513 heap_free(reginfo);
516 return ref;
519 static HRESULT WINAPI RegistrationInfo_QueryInterface(IRegistrationInfo *iface, REFIID riid, void **obj)
521 if (!riid || !obj) return E_INVALIDARG;
523 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
525 if (IsEqualGUID(riid, &IID_IRegistrationInfo) ||
526 IsEqualGUID(riid, &IID_IDispatch) ||
527 IsEqualGUID(riid, &IID_IUnknown))
529 IRegistrationInfo_AddRef(iface);
530 *obj = iface;
531 return S_OK;
534 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
535 *obj = NULL;
536 return E_NOINTERFACE;
539 static HRESULT WINAPI RegistrationInfo_GetTypeInfoCount(IRegistrationInfo *iface, UINT *count)
541 FIXME("%p,%p: stub\n", iface, count);
542 return E_NOTIMPL;
545 static HRESULT WINAPI RegistrationInfo_GetTypeInfo(IRegistrationInfo *iface, UINT index, LCID lcid, ITypeInfo **info)
547 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
548 return E_NOTIMPL;
551 static HRESULT WINAPI RegistrationInfo_GetIDsOfNames(IRegistrationInfo *iface, REFIID riid, LPOLESTR *names,
552 UINT count, LCID lcid, DISPID *dispid)
554 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
555 return E_NOTIMPL;
558 static HRESULT WINAPI RegistrationInfo_Invoke(IRegistrationInfo *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
559 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
561 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
562 params, result, excepinfo, argerr);
563 return E_NOTIMPL;
566 static HRESULT WINAPI RegistrationInfo_get_Description(IRegistrationInfo *iface, BSTR *description)
568 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
570 TRACE("%p,%p\n", iface, description);
572 if (!description) return E_POINTER;
574 if (!reginfo->description) *description = NULL;
575 else if (!(*description = SysAllocString(reginfo->description))) return E_OUTOFMEMORY;
577 return S_OK;
580 static HRESULT WINAPI RegistrationInfo_put_Description(IRegistrationInfo *iface, BSTR description)
582 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
583 WCHAR *str = NULL;
585 TRACE("%p,%s\n", iface, debugstr_w(description));
587 if (description && !(str = heap_strdupW(description))) return E_OUTOFMEMORY;
588 heap_free(reginfo->description);
589 reginfo->description = str;
590 return S_OK;
593 static HRESULT WINAPI RegistrationInfo_get_Author(IRegistrationInfo *iface, BSTR *author)
595 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
597 TRACE("%p,%p\n", iface, author);
599 if (!author) return E_POINTER;
601 if (!reginfo->author) *author = NULL;
602 else if (!(*author = SysAllocString(reginfo->author))) return E_OUTOFMEMORY;
604 return S_OK;
607 static HRESULT WINAPI RegistrationInfo_put_Author(IRegistrationInfo *iface, BSTR author)
609 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
610 WCHAR *str = NULL;
612 TRACE("%p,%s\n", iface, debugstr_w(author));
614 if (author && !(str = heap_strdupW(author))) return E_OUTOFMEMORY;
615 heap_free(reginfo->author);
616 reginfo->author = str;
617 return S_OK;
620 static HRESULT WINAPI RegistrationInfo_get_Version(IRegistrationInfo *iface, BSTR *version)
622 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
624 TRACE("%p,%p\n", iface, version);
626 if (!version) return E_POINTER;
628 if (!reginfo->version) *version = NULL;
629 else if (!(*version = SysAllocString(reginfo->version))) return E_OUTOFMEMORY;
631 return S_OK;
634 static HRESULT WINAPI RegistrationInfo_put_Version(IRegistrationInfo *iface, BSTR version)
636 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
637 WCHAR *str = NULL;
639 TRACE("%p,%s\n", iface, debugstr_w(version));
641 if (version && !(str = heap_strdupW(version))) return E_OUTOFMEMORY;
642 heap_free(reginfo->version);
643 reginfo->version = str;
644 return S_OK;
647 static HRESULT WINAPI RegistrationInfo_get_Date(IRegistrationInfo *iface, BSTR *date)
649 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
651 TRACE("%p,%p\n", iface, date);
653 if (!date) return E_POINTER;
655 if (!reginfo->date) *date = NULL;
656 else if (!(*date = SysAllocString(reginfo->date))) return E_OUTOFMEMORY;
658 return S_OK;
661 static HRESULT WINAPI RegistrationInfo_put_Date(IRegistrationInfo *iface, BSTR date)
663 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
664 WCHAR *str = NULL;
666 TRACE("%p,%s\n", iface, debugstr_w(date));
668 if (date && !(str = heap_strdupW(date))) return E_OUTOFMEMORY;
669 heap_free(reginfo->date);
670 reginfo->date = str;
671 return S_OK;
674 static HRESULT WINAPI RegistrationInfo_get_Documentation(IRegistrationInfo *iface, BSTR *doc)
676 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
678 TRACE("%p,%p\n", iface, doc);
680 if (!doc) return E_POINTER;
682 if (!reginfo->documentation) *doc = NULL;
683 else if (!(*doc = SysAllocString(reginfo->documentation))) return E_OUTOFMEMORY;
685 return S_OK;
688 static HRESULT WINAPI RegistrationInfo_put_Documentation(IRegistrationInfo *iface, BSTR doc)
690 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
691 WCHAR *str = NULL;
693 TRACE("%p,%s\n", iface, debugstr_w(doc));
695 if (doc && !(str = heap_strdupW(doc))) return E_OUTOFMEMORY;
696 heap_free(reginfo->documentation);
697 reginfo->documentation = str;
698 return S_OK;
701 static HRESULT WINAPI RegistrationInfo_get_XmlText(IRegistrationInfo *iface, BSTR *xml)
703 FIXME("%p,%p: stub\n", iface, xml);
704 return E_NOTIMPL;
707 static HRESULT WINAPI RegistrationInfo_put_XmlText(IRegistrationInfo *iface, BSTR xml)
709 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
710 return E_NOTIMPL;
713 static HRESULT WINAPI RegistrationInfo_get_URI(IRegistrationInfo *iface, BSTR *uri)
715 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
717 TRACE("%p,%p\n", iface, uri);
719 if (!uri) return E_POINTER;
721 if (!reginfo->uri) *uri = NULL;
722 else if (!(*uri = SysAllocString(reginfo->uri))) return E_OUTOFMEMORY;
724 return S_OK;
727 static HRESULT WINAPI RegistrationInfo_put_URI(IRegistrationInfo *iface, BSTR uri)
729 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
730 WCHAR *str = NULL;
732 TRACE("%p,%s\n", iface, debugstr_w(uri));
734 if (uri && !(str = heap_strdupW(uri))) return E_OUTOFMEMORY;
735 heap_free(reginfo->uri);
736 reginfo->uri = str;
737 return S_OK;
740 static HRESULT WINAPI RegistrationInfo_get_SecurityDescriptor(IRegistrationInfo *iface, VARIANT *sddl)
742 FIXME("%p,%p: stub\n", iface, sddl);
743 return E_NOTIMPL;
746 static HRESULT WINAPI RegistrationInfo_put_SecurityDescriptor(IRegistrationInfo *iface, VARIANT sddl)
748 FIXME("%p,%s: stub\n", iface, debugstr_variant(&sddl));
749 return S_OK;
752 static HRESULT WINAPI RegistrationInfo_get_Source(IRegistrationInfo *iface, BSTR *source)
754 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
756 TRACE("%p,%p\n", iface, source);
758 if (!source) return E_POINTER;
760 if (!reginfo->source) *source = NULL;
761 else if (!(*source = SysAllocString(reginfo->source))) return E_OUTOFMEMORY;
763 return S_OK;
766 static HRESULT WINAPI RegistrationInfo_put_Source(IRegistrationInfo *iface, BSTR source)
768 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
769 WCHAR *str = NULL;
771 TRACE("%p,%s\n", iface, debugstr_w(source));
773 if (source && !(str = heap_strdupW(source))) return E_OUTOFMEMORY;
774 heap_free(reginfo->source);
775 reginfo->source = str;
776 return S_OK;
779 static const IRegistrationInfoVtbl RegistrationInfo_vtbl =
781 RegistrationInfo_QueryInterface,
782 RegistrationInfo_AddRef,
783 RegistrationInfo_Release,
784 RegistrationInfo_GetTypeInfoCount,
785 RegistrationInfo_GetTypeInfo,
786 RegistrationInfo_GetIDsOfNames,
787 RegistrationInfo_Invoke,
788 RegistrationInfo_get_Description,
789 RegistrationInfo_put_Description,
790 RegistrationInfo_get_Author,
791 RegistrationInfo_put_Author,
792 RegistrationInfo_get_Version,
793 RegistrationInfo_put_Version,
794 RegistrationInfo_get_Date,
795 RegistrationInfo_put_Date,
796 RegistrationInfo_get_Documentation,
797 RegistrationInfo_put_Documentation,
798 RegistrationInfo_get_XmlText,
799 RegistrationInfo_put_XmlText,
800 RegistrationInfo_get_URI,
801 RegistrationInfo_put_URI,
802 RegistrationInfo_get_SecurityDescriptor,
803 RegistrationInfo_put_SecurityDescriptor,
804 RegistrationInfo_get_Source,
805 RegistrationInfo_put_Source
808 static HRESULT RegistrationInfo_create(IRegistrationInfo **obj)
810 registration_info *reginfo;
812 reginfo = heap_alloc_zero(sizeof(*reginfo));
813 if (!reginfo) return E_OUTOFMEMORY;
815 reginfo->IRegistrationInfo_iface.lpVtbl = &RegistrationInfo_vtbl;
816 reginfo->ref = 1;
817 *obj = &reginfo->IRegistrationInfo_iface;
819 TRACE("created %p\n", *obj);
821 return S_OK;
824 typedef struct
826 ITaskSettings ITaskSettings_iface;
827 LONG ref;
828 WCHAR *restart_interval;
829 WCHAR *execution_time_limit;
830 WCHAR *delete_expired_task_after;
831 int restart_count;
832 int priority;
833 TASK_INSTANCES_POLICY policy;
834 TASK_COMPATIBILITY compatibility;
835 BOOL allow_on_demand_start;
836 BOOL stop_if_going_on_batteries;
837 BOOL disallow_start_if_on_batteries;
838 BOOL allow_hard_terminate;
839 BOOL start_when_available;
840 BOOL run_only_if_network_available;
841 BOOL enabled;
842 BOOL hidden;
843 BOOL run_only_if_idle;
844 BOOL wake_to_run;
845 } TaskSettings;
847 static inline TaskSettings *impl_from_ITaskSettings(ITaskSettings *iface)
849 return CONTAINING_RECORD(iface, TaskSettings, ITaskSettings_iface);
852 static ULONG WINAPI TaskSettings_AddRef(ITaskSettings *iface)
854 TaskSettings *taskset = impl_from_ITaskSettings(iface);
855 return InterlockedIncrement(&taskset->ref);
858 static ULONG WINAPI TaskSettings_Release(ITaskSettings *iface)
860 TaskSettings *taskset = impl_from_ITaskSettings(iface);
861 LONG ref = InterlockedDecrement(&taskset->ref);
863 if (!ref)
865 TRACE("destroying %p\n", iface);
866 heap_free(taskset->restart_interval);
867 heap_free(taskset->execution_time_limit);
868 heap_free(taskset->delete_expired_task_after);
869 heap_free(taskset);
872 return ref;
875 static HRESULT WINAPI TaskSettings_QueryInterface(ITaskSettings *iface, REFIID riid, void **obj)
877 if (!riid || !obj) return E_INVALIDARG;
879 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
881 if (IsEqualGUID(riid, &IID_ITaskSettings) ||
882 IsEqualGUID(riid, &IID_IDispatch) ||
883 IsEqualGUID(riid, &IID_IUnknown))
885 ITaskSettings_AddRef(iface);
886 *obj = iface;
887 return S_OK;
890 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
891 *obj = NULL;
892 return E_NOINTERFACE;
895 static HRESULT WINAPI TaskSettings_GetTypeInfoCount(ITaskSettings *iface, UINT *count)
897 FIXME("%p,%p: stub\n", iface, count);
898 return E_NOTIMPL;
901 static HRESULT WINAPI TaskSettings_GetTypeInfo(ITaskSettings *iface, UINT index, LCID lcid, ITypeInfo **info)
903 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
904 return E_NOTIMPL;
907 static HRESULT WINAPI TaskSettings_GetIDsOfNames(ITaskSettings *iface, REFIID riid, LPOLESTR *names,
908 UINT count, LCID lcid, DISPID *dispid)
910 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
911 return E_NOTIMPL;
914 static HRESULT WINAPI TaskSettings_Invoke(ITaskSettings *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
915 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
917 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
918 params, result, excepinfo, argerr);
919 return E_NOTIMPL;
922 static HRESULT WINAPI TaskSettings_get_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL *allow)
924 TaskSettings *taskset = impl_from_ITaskSettings(iface);
926 TRACE("%p,%p\n", iface, allow);
928 if (!allow) return E_POINTER;
930 *allow = taskset->allow_on_demand_start ? VARIANT_TRUE : VARIANT_FALSE;
932 return S_OK;
935 static HRESULT WINAPI TaskSettings_put_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL allow)
937 TaskSettings *taskset = impl_from_ITaskSettings(iface);
939 TRACE("%p,%d\n", iface, allow);
941 taskset->allow_on_demand_start = !!allow;
943 return S_OK;
946 static HRESULT WINAPI TaskSettings_get_RestartInterval(ITaskSettings *iface, BSTR *interval)
948 TaskSettings *taskset = impl_from_ITaskSettings(iface);
950 TRACE("%p,%p\n", iface, interval);
952 if (!interval) return E_POINTER;
954 if (!taskset->restart_interval)
956 *interval = NULL;
957 return S_OK;
960 if (!taskset->restart_interval) *interval = NULL;
961 else if (!(*interval = SysAllocString(taskset->restart_interval))) return E_OUTOFMEMORY;
963 return S_OK;
966 static HRESULT WINAPI TaskSettings_put_RestartInterval(ITaskSettings *iface, BSTR interval)
968 TaskSettings *taskset = impl_from_ITaskSettings(iface);
969 WCHAR *str = NULL;
971 TRACE("%p,%s\n", iface, debugstr_w(interval));
973 if (interval && !(str = heap_strdupW(interval))) return E_OUTOFMEMORY;
974 heap_free(taskset->restart_interval);
975 taskset->restart_interval = str;
977 return S_OK;
980 static HRESULT WINAPI TaskSettings_get_RestartCount(ITaskSettings *iface, INT *count)
982 TaskSettings *taskset = impl_from_ITaskSettings(iface);
984 TRACE("%p,%p\n", iface, count);
986 if (!count) return E_POINTER;
988 *count = taskset->restart_count;
990 return S_OK;
993 static HRESULT WINAPI TaskSettings_put_RestartCount(ITaskSettings *iface, INT count)
995 TaskSettings *taskset = impl_from_ITaskSettings(iface);
997 TRACE("%p,%d\n", iface, count);
999 taskset->restart_count = count;
1001 return S_OK;
1004 static HRESULT WINAPI TaskSettings_get_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY *policy)
1006 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1008 TRACE("%p,%p\n", iface, policy);
1010 if (!policy) return E_POINTER;
1012 *policy = taskset->policy;
1014 return S_OK;
1017 static HRESULT WINAPI TaskSettings_put_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY policy)
1019 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1021 TRACE("%p,%d\n", iface, policy);
1023 taskset->policy = policy;
1025 return S_OK;
1028 static HRESULT WINAPI TaskSettings_get_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL *stop)
1030 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1032 TRACE("%p,%p\n", iface, stop);
1034 if (!stop) return E_POINTER;
1036 *stop = taskset->stop_if_going_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1038 return S_OK;
1041 static HRESULT WINAPI TaskSettings_put_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL stop)
1043 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1045 TRACE("%p,%d\n", iface, stop);
1047 taskset->stop_if_going_on_batteries = !!stop;
1049 return S_OK;
1052 static HRESULT WINAPI TaskSettings_get_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL *disallow)
1054 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1056 TRACE("%p,%p\n", iface, disallow);
1058 if (!disallow) return E_POINTER;
1060 *disallow = taskset->disallow_start_if_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1062 return S_OK;
1065 static HRESULT WINAPI TaskSettings_put_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL disallow)
1067 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1069 TRACE("%p,%d\n", iface, disallow);
1071 taskset->disallow_start_if_on_batteries = !!disallow;
1073 return S_OK;
1076 static HRESULT WINAPI TaskSettings_get_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL *allow)
1078 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1080 TRACE("%p,%p\n", iface, allow);
1082 if (!allow) return E_POINTER;
1084 *allow = taskset->allow_hard_terminate ? VARIANT_TRUE : VARIANT_FALSE;
1086 return S_OK;
1089 static HRESULT WINAPI TaskSettings_put_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL allow)
1091 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1093 TRACE("%p,%d\n", iface, allow);
1095 taskset->allow_hard_terminate = !!allow;
1097 return S_OK;
1100 static HRESULT WINAPI TaskSettings_get_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL *start)
1102 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1104 TRACE("%p,%p\n", iface, start);
1106 if (!start) return E_POINTER;
1108 *start = taskset->start_when_available ? VARIANT_TRUE : VARIANT_FALSE;
1110 return S_OK;
1113 static HRESULT WINAPI TaskSettings_put_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL start)
1115 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1117 TRACE("%p,%d\n", iface, start);
1119 taskset->start_when_available = !!start;
1121 return S_OK;
1124 static HRESULT WINAPI TaskSettings_get_XmlText(ITaskSettings *iface, BSTR *xml)
1126 FIXME("%p,%p: stub\n", iface, xml);
1127 return E_NOTIMPL;
1130 static HRESULT WINAPI TaskSettings_put_XmlText(ITaskSettings *iface, BSTR xml)
1132 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
1133 return E_NOTIMPL;
1136 static HRESULT WINAPI TaskSettings_get_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL *run)
1138 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1140 TRACE("%p,%p\n", iface, run);
1142 if (!run) return E_POINTER;
1144 *run = taskset->run_only_if_network_available ? VARIANT_TRUE : VARIANT_FALSE;
1146 return S_OK;
1149 static HRESULT WINAPI TaskSettings_put_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL run)
1151 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1153 TRACE("%p,%d\n", iface, run);
1155 taskset->run_only_if_network_available = !!run;
1157 return S_OK;
1160 static HRESULT WINAPI TaskSettings_get_ExecutionTimeLimit(ITaskSettings *iface, BSTR *limit)
1162 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1164 TRACE("%p,%p\n", iface, limit);
1166 if (!limit) return E_POINTER;
1168 if (!taskset->execution_time_limit)
1170 *limit = NULL;
1171 return S_OK;
1174 if (!taskset->execution_time_limit) *limit = NULL;
1175 else if (!(*limit = SysAllocString(taskset->execution_time_limit))) return E_OUTOFMEMORY;
1177 return S_OK;
1180 static HRESULT WINAPI TaskSettings_put_ExecutionTimeLimit(ITaskSettings *iface, BSTR limit)
1182 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1183 WCHAR *str = NULL;
1185 TRACE("%p,%s\n", iface, debugstr_w(limit));
1187 if (limit && !(str = heap_strdupW(limit))) return E_OUTOFMEMORY;
1188 heap_free(taskset->execution_time_limit);
1189 taskset->execution_time_limit = str;
1191 return S_OK;
1194 static HRESULT WINAPI TaskSettings_get_Enabled(ITaskSettings *iface, VARIANT_BOOL *enabled)
1196 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1198 TRACE("%p,%p\n", iface, enabled);
1200 if (!enabled) return E_POINTER;
1202 *enabled = taskset->enabled ? VARIANT_TRUE : VARIANT_FALSE;
1204 return S_OK;
1207 static HRESULT WINAPI TaskSettings_put_Enabled(ITaskSettings *iface, VARIANT_BOOL enabled)
1209 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1211 TRACE("%p,%d\n", iface, enabled);
1213 taskset->enabled = !!enabled;
1215 return S_OK;
1218 static HRESULT WINAPI TaskSettings_get_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR *delay)
1220 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1222 TRACE("%p,%p\n", iface, delay);
1224 if (!delay) return E_POINTER;
1226 if (!taskset->delete_expired_task_after) *delay = NULL;
1227 else if (!(*delay = SysAllocString(taskset->delete_expired_task_after))) return E_OUTOFMEMORY;
1229 return S_OK;
1232 static HRESULT WINAPI TaskSettings_put_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR delay)
1234 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1235 WCHAR *str = NULL;
1237 TRACE("%p,%s\n", iface, debugstr_w(delay));
1239 if (delay && !(str = heap_strdupW(delay))) return E_OUTOFMEMORY;
1240 heap_free(taskset->delete_expired_task_after);
1241 taskset->delete_expired_task_after = str;
1243 return S_OK;
1246 static HRESULT WINAPI TaskSettings_get_Priority(ITaskSettings *iface, INT *priority)
1248 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1250 TRACE("%p,%p\n", iface, priority);
1252 if (!priority) return E_POINTER;
1254 *priority = taskset->priority;
1256 return S_OK;
1259 static HRESULT WINAPI TaskSettings_put_Priority(ITaskSettings *iface, INT priority)
1261 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1263 TRACE("%p,%d\n", iface, priority);
1265 taskset->priority = priority;
1267 return S_OK;
1270 static HRESULT WINAPI TaskSettings_get_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY *level)
1272 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1274 TRACE("%p,%p\n", iface, level);
1276 if (!level) return E_POINTER;
1278 *level = taskset->compatibility;
1280 return S_OK;
1283 static HRESULT WINAPI TaskSettings_put_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY level)
1285 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1287 TRACE("%p,%d\n", iface, level);
1289 taskset->compatibility = level;
1291 return S_OK;
1294 static HRESULT WINAPI TaskSettings_get_Hidden(ITaskSettings *iface, VARIANT_BOOL *hidden)
1296 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1298 TRACE("%p,%p\n", iface, hidden);
1300 if (!hidden) return E_POINTER;
1302 *hidden = taskset->hidden ? VARIANT_TRUE : VARIANT_FALSE;
1304 return S_OK;
1307 static HRESULT WINAPI TaskSettings_put_Hidden(ITaskSettings *iface, VARIANT_BOOL hidden)
1309 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1311 TRACE("%p,%d\n", iface, hidden);
1313 taskset->hidden = !!hidden;
1315 return S_OK;
1318 static HRESULT WINAPI TaskSettings_get_IdleSettings(ITaskSettings *iface, IIdleSettings **settings)
1320 FIXME("%p,%p: stub\n", iface, settings);
1321 return E_NOTIMPL;
1324 static HRESULT WINAPI TaskSettings_put_IdleSettings(ITaskSettings *iface, IIdleSettings *settings)
1326 FIXME("%p,%p: stub\n", iface, settings);
1327 return E_NOTIMPL;
1330 static HRESULT WINAPI TaskSettings_get_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL *run)
1332 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1334 TRACE("%p,%p\n", iface, run);
1336 if (!run) return E_POINTER;
1338 *run = taskset->run_only_if_idle ? VARIANT_TRUE : VARIANT_FALSE;
1340 return S_OK;
1343 static HRESULT WINAPI TaskSettings_put_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL run)
1345 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1347 TRACE("%p,%d\n", iface, run);
1349 taskset->run_only_if_idle = !!run;
1351 return S_OK;
1354 static HRESULT WINAPI TaskSettings_get_WakeToRun(ITaskSettings *iface, VARIANT_BOOL *wake)
1356 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1358 TRACE("%p,%p\n", iface, wake);
1360 if (!wake) return E_POINTER;
1362 *wake = taskset->wake_to_run ? VARIANT_TRUE : VARIANT_FALSE;
1364 return S_OK;
1367 static HRESULT WINAPI TaskSettings_put_WakeToRun(ITaskSettings *iface, VARIANT_BOOL wake)
1369 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1371 TRACE("%p,%d\n", iface, wake);
1373 taskset->wake_to_run = !!wake;
1375 return S_OK;
1378 static HRESULT WINAPI TaskSettings_get_NetworkSettings(ITaskSettings *iface, INetworkSettings **settings)
1380 FIXME("%p,%p: stub\n", iface, settings);
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI TaskSettings_put_NetworkSettings(ITaskSettings *iface, INetworkSettings *settings)
1386 FIXME("%p,%p: stub\n", iface, settings);
1387 return E_NOTIMPL;
1390 static const ITaskSettingsVtbl TaskSettings_vtbl =
1392 TaskSettings_QueryInterface,
1393 TaskSettings_AddRef,
1394 TaskSettings_Release,
1395 TaskSettings_GetTypeInfoCount,
1396 TaskSettings_GetTypeInfo,
1397 TaskSettings_GetIDsOfNames,
1398 TaskSettings_Invoke,
1399 TaskSettings_get_AllowDemandStart,
1400 TaskSettings_put_AllowDemandStart,
1401 TaskSettings_get_RestartInterval,
1402 TaskSettings_put_RestartInterval,
1403 TaskSettings_get_RestartCount,
1404 TaskSettings_put_RestartCount,
1405 TaskSettings_get_MultipleInstances,
1406 TaskSettings_put_MultipleInstances,
1407 TaskSettings_get_StopIfGoingOnBatteries,
1408 TaskSettings_put_StopIfGoingOnBatteries,
1409 TaskSettings_get_DisallowStartIfOnBatteries,
1410 TaskSettings_put_DisallowStartIfOnBatteries,
1411 TaskSettings_get_AllowHardTerminate,
1412 TaskSettings_put_AllowHardTerminate,
1413 TaskSettings_get_StartWhenAvailable,
1414 TaskSettings_put_StartWhenAvailable,
1415 TaskSettings_get_XmlText,
1416 TaskSettings_put_XmlText,
1417 TaskSettings_get_RunOnlyIfNetworkAvailable,
1418 TaskSettings_put_RunOnlyIfNetworkAvailable,
1419 TaskSettings_get_ExecutionTimeLimit,
1420 TaskSettings_put_ExecutionTimeLimit,
1421 TaskSettings_get_Enabled,
1422 TaskSettings_put_Enabled,
1423 TaskSettings_get_DeleteExpiredTaskAfter,
1424 TaskSettings_put_DeleteExpiredTaskAfter,
1425 TaskSettings_get_Priority,
1426 TaskSettings_put_Priority,
1427 TaskSettings_get_Compatibility,
1428 TaskSettings_put_Compatibility,
1429 TaskSettings_get_Hidden,
1430 TaskSettings_put_Hidden,
1431 TaskSettings_get_IdleSettings,
1432 TaskSettings_put_IdleSettings,
1433 TaskSettings_get_RunOnlyIfIdle,
1434 TaskSettings_put_RunOnlyIfIdle,
1435 TaskSettings_get_WakeToRun,
1436 TaskSettings_put_WakeToRun,
1437 TaskSettings_get_NetworkSettings,
1438 TaskSettings_put_NetworkSettings
1441 static HRESULT TaskSettings_create(ITaskSettings **obj)
1443 static const WCHAR exec_time_limit[] = { 'P','T','7','2','H',0 };
1444 TaskSettings *taskset;
1446 taskset = heap_alloc(sizeof(*taskset));
1447 if (!taskset) return E_OUTOFMEMORY;
1449 taskset->ITaskSettings_iface.lpVtbl = &TaskSettings_vtbl;
1450 taskset->ref = 1;
1451 /* set the defaults */
1452 taskset->restart_interval = NULL;
1453 taskset->execution_time_limit = heap_strdupW(exec_time_limit);
1454 taskset->delete_expired_task_after = NULL;
1455 taskset->restart_count = 0;
1456 taskset->priority = 7;
1457 taskset->policy = TASK_INSTANCES_IGNORE_NEW;
1458 taskset->compatibility = TASK_COMPATIBILITY_V2;
1459 taskset->allow_on_demand_start = TRUE;
1460 taskset->stop_if_going_on_batteries = TRUE;
1461 taskset->disallow_start_if_on_batteries = TRUE;
1462 taskset->allow_hard_terminate = TRUE;
1463 taskset->start_when_available = FALSE;
1464 taskset->run_only_if_network_available = FALSE;
1465 taskset->enabled = TRUE;
1466 taskset->hidden = FALSE;
1467 taskset->run_only_if_idle = FALSE;
1468 taskset->wake_to_run = FALSE;
1470 *obj = &taskset->ITaskSettings_iface;
1472 TRACE("created %p\n", *obj);
1474 return S_OK;
1477 typedef struct
1479 IPrincipal IPrincipal_iface;
1480 LONG ref;
1481 } Principal;
1483 static inline Principal *impl_from_IPrincipal(IPrincipal *iface)
1485 return CONTAINING_RECORD(iface, Principal, IPrincipal_iface);
1488 static ULONG WINAPI Principal_AddRef(IPrincipal *iface)
1490 Principal *principal = impl_from_IPrincipal(iface);
1491 return InterlockedIncrement(&principal->ref);
1494 static ULONG WINAPI Principal_Release(IPrincipal *iface)
1496 Principal *principal = impl_from_IPrincipal(iface);
1497 LONG ref = InterlockedDecrement(&principal->ref);
1499 if (!ref)
1501 TRACE("destroying %p\n", iface);
1502 heap_free(principal);
1505 return ref;
1508 static HRESULT WINAPI Principal_QueryInterface(IPrincipal *iface, REFIID riid, void **obj)
1510 if (!riid || !obj) return E_INVALIDARG;
1512 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1514 if (IsEqualGUID(riid, &IID_IPrincipal) ||
1515 IsEqualGUID(riid, &IID_IDispatch) ||
1516 IsEqualGUID(riid, &IID_IUnknown))
1518 IPrincipal_AddRef(iface);
1519 *obj = iface;
1520 return S_OK;
1523 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1524 *obj = NULL;
1525 return E_NOINTERFACE;
1528 static HRESULT WINAPI Principal_GetTypeInfoCount(IPrincipal *iface, UINT *count)
1530 FIXME("%p,%p: stub\n", iface, count);
1531 return E_NOTIMPL;
1534 static HRESULT WINAPI Principal_GetTypeInfo(IPrincipal *iface, UINT index, LCID lcid, ITypeInfo **info)
1536 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1537 return E_NOTIMPL;
1540 static HRESULT WINAPI Principal_GetIDsOfNames(IPrincipal *iface, REFIID riid, LPOLESTR *names,
1541 UINT count, LCID lcid, DISPID *dispid)
1543 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1544 return E_NOTIMPL;
1547 static HRESULT WINAPI Principal_Invoke(IPrincipal *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1548 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1550 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1551 params, result, excepinfo, argerr);
1552 return E_NOTIMPL;
1555 static HRESULT WINAPI Principal_get_Id(IPrincipal *iface, BSTR *id)
1557 FIXME("%p,%p: stub\n", iface, id);
1558 return E_NOTIMPL;
1561 static HRESULT WINAPI Principal_put_Id(IPrincipal *iface, BSTR id)
1563 FIXME("%p,%s: stub\n", iface, debugstr_w(id));
1564 return S_OK;
1567 static HRESULT WINAPI Principal_get_DisplayName(IPrincipal *iface, BSTR *name)
1569 FIXME("%p,%p: stub\n", iface, name);
1570 return E_NOTIMPL;
1573 static HRESULT WINAPI Principal_put_DisplayName(IPrincipal *iface, BSTR name)
1575 FIXME("%p,%s: stub\n", iface, debugstr_w(name));
1576 return E_NOTIMPL;
1579 static HRESULT WINAPI Principal_get_UserId(IPrincipal *iface, BSTR *user_id)
1581 FIXME("%p,%p: stub\n", iface, user_id);
1582 return E_NOTIMPL;
1585 static HRESULT WINAPI Principal_put_UserId(IPrincipal *iface, BSTR user_id)
1587 FIXME("%p,%s: stub\n", iface, debugstr_w(user_id));
1588 return S_OK;
1591 static HRESULT WINAPI Principal_get_LogonType(IPrincipal *iface, TASK_LOGON_TYPE *logon_type)
1593 FIXME("%p,%p: stub\n", iface, logon_type);
1594 return E_NOTIMPL;
1597 static HRESULT WINAPI Principal_put_LogonType(IPrincipal *iface, TASK_LOGON_TYPE logon_type)
1599 FIXME("%p,%u: stub\n", iface, logon_type);
1600 return E_NOTIMPL;
1603 static HRESULT WINAPI Principal_get_GroupId(IPrincipal *iface, BSTR *group_id)
1605 FIXME("%p,%p: stub\n", iface, group_id);
1606 return E_NOTIMPL;
1609 static HRESULT WINAPI Principal_put_GroupId(IPrincipal *iface, BSTR group_id)
1611 FIXME("%p,%s: stub\n", iface, debugstr_w(group_id));
1612 return E_NOTIMPL;
1615 static HRESULT WINAPI Principal_get_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE *run_level)
1617 FIXME("%p,%p: stub\n", iface, run_level);
1618 return E_NOTIMPL;
1621 static HRESULT WINAPI Principal_put_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE run_level)
1623 FIXME("%p,%u: stub\n", iface, run_level);
1624 return E_NOTIMPL;
1627 static const IPrincipalVtbl Principal_vtbl =
1629 Principal_QueryInterface,
1630 Principal_AddRef,
1631 Principal_Release,
1632 Principal_GetTypeInfoCount,
1633 Principal_GetTypeInfo,
1634 Principal_GetIDsOfNames,
1635 Principal_Invoke,
1636 Principal_get_Id,
1637 Principal_put_Id,
1638 Principal_get_DisplayName,
1639 Principal_put_DisplayName,
1640 Principal_get_UserId,
1641 Principal_put_UserId,
1642 Principal_get_LogonType,
1643 Principal_put_LogonType,
1644 Principal_get_GroupId,
1645 Principal_put_GroupId,
1646 Principal_get_RunLevel,
1647 Principal_put_RunLevel
1650 static HRESULT Principal_create(IPrincipal **obj)
1652 Principal *principal;
1654 principal = heap_alloc(sizeof(*principal));
1655 if (!principal) return E_OUTOFMEMORY;
1657 principal->IPrincipal_iface.lpVtbl = &Principal_vtbl;
1658 principal->ref = 1;
1660 *obj = &principal->IPrincipal_iface;
1662 TRACE("created %p\n", *obj);
1664 return S_OK;
1667 typedef struct
1669 IExecAction IExecAction_iface;
1670 LONG ref;
1671 WCHAR *path;
1672 WCHAR *directory;
1673 WCHAR *args;
1674 WCHAR *id;
1675 } ExecAction;
1677 static inline ExecAction *impl_from_IExecAction(IExecAction *iface)
1679 return CONTAINING_RECORD(iface, ExecAction, IExecAction_iface);
1682 static ULONG WINAPI ExecAction_AddRef(IExecAction *iface)
1684 ExecAction *action = impl_from_IExecAction(iface);
1685 return InterlockedIncrement(&action->ref);
1688 static ULONG WINAPI ExecAction_Release(IExecAction *iface)
1690 ExecAction *action = impl_from_IExecAction(iface);
1691 LONG ref = InterlockedDecrement(&action->ref);
1693 if (!ref)
1695 TRACE("destroying %p\n", iface);
1696 heap_free(action->path);
1697 heap_free(action->directory);
1698 heap_free(action->args);
1699 heap_free(action->id);
1700 heap_free(action);
1703 return ref;
1706 static HRESULT WINAPI ExecAction_QueryInterface(IExecAction *iface, REFIID riid, void **obj)
1708 if (!riid || !obj) return E_INVALIDARG;
1710 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1712 if (IsEqualGUID(riid, &IID_IExecAction) ||
1713 IsEqualGUID(riid, &IID_IAction) ||
1714 IsEqualGUID(riid, &IID_IDispatch) ||
1715 IsEqualGUID(riid, &IID_IUnknown))
1717 IExecAction_AddRef(iface);
1718 *obj = iface;
1719 return S_OK;
1722 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1723 *obj = NULL;
1724 return E_NOINTERFACE;
1727 static HRESULT WINAPI ExecAction_GetTypeInfoCount(IExecAction *iface, UINT *count)
1729 FIXME("%p,%p: stub\n", iface, count);
1730 return E_NOTIMPL;
1733 static HRESULT WINAPI ExecAction_GetTypeInfo(IExecAction *iface, UINT index, LCID lcid, ITypeInfo **info)
1735 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1736 return E_NOTIMPL;
1739 static HRESULT WINAPI ExecAction_GetIDsOfNames(IExecAction *iface, REFIID riid, LPOLESTR *names,
1740 UINT count, LCID lcid, DISPID *dispid)
1742 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1743 return E_NOTIMPL;
1746 static HRESULT WINAPI ExecAction_Invoke(IExecAction *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1747 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1749 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1750 params, result, excepinfo, argerr);
1751 return E_NOTIMPL;
1754 static HRESULT WINAPI ExecAction_get_Id(IExecAction *iface, BSTR *id)
1756 ExecAction *action = impl_from_IExecAction(iface);
1758 TRACE("%p,%p\n", iface, id);
1760 if (!id) return E_POINTER;
1762 if (!action->id) *id = NULL;
1763 else if (!(*id = SysAllocString(action->id))) return E_OUTOFMEMORY;
1765 return S_OK;
1768 static HRESULT WINAPI ExecAction_put_Id(IExecAction *iface, BSTR id)
1770 ExecAction *action = impl_from_IExecAction(iface);
1771 WCHAR *str = NULL;
1773 TRACE("%p,%s\n", iface, debugstr_w(id));
1775 if (id && !(str = heap_strdupW((id)))) return E_OUTOFMEMORY;
1776 heap_free(action->id);
1777 action->id = str;
1779 return S_OK;
1782 static HRESULT WINAPI ExecAction_get_Type(IExecAction *iface, TASK_ACTION_TYPE *type)
1784 TRACE("%p,%p\n", iface, type);
1786 if (!type) return E_POINTER;
1788 *type = TASK_ACTION_EXEC;
1790 return S_OK;
1793 static HRESULT WINAPI ExecAction_get_Path(IExecAction *iface, BSTR *path)
1795 ExecAction *action = impl_from_IExecAction(iface);
1797 TRACE("%p,%p\n", iface, path);
1799 if (!path) return E_POINTER;
1801 if (!action->path) *path = NULL;
1802 else if (!(*path = SysAllocString(action->path))) return E_OUTOFMEMORY;
1804 return S_OK;
1807 static HRESULT WINAPI ExecAction_put_Path(IExecAction *iface, BSTR path)
1809 ExecAction *action = impl_from_IExecAction(iface);
1810 WCHAR *str = NULL;
1812 TRACE("%p,%s\n", iface, debugstr_w(path));
1814 if (path && !(str = heap_strdupW((path)))) return E_OUTOFMEMORY;
1815 heap_free(action->path);
1816 action->path = str;
1818 return S_OK;
1821 static HRESULT WINAPI ExecAction_get_Arguments(IExecAction *iface, BSTR *arguments)
1823 ExecAction *action = impl_from_IExecAction(iface);
1825 TRACE("%p,%p\n", iface, arguments);
1827 if (!arguments) return E_POINTER;
1829 if (!action->args) *arguments = NULL;
1830 else if (!(*arguments = SysAllocString(action->args))) return E_OUTOFMEMORY;
1832 return S_OK;
1835 static HRESULT WINAPI ExecAction_put_Arguments(IExecAction *iface, BSTR arguments)
1837 ExecAction *action = impl_from_IExecAction(iface);
1838 WCHAR *str = NULL;
1840 TRACE("%p,%s\n", iface, debugstr_w(arguments));
1842 if (arguments && !(str = heap_strdupW((arguments)))) return E_OUTOFMEMORY;
1843 heap_free(action->args);
1844 action->args = str;
1846 return S_OK;
1849 static HRESULT WINAPI ExecAction_get_WorkingDirectory(IExecAction *iface, BSTR *directory)
1851 ExecAction *action = impl_from_IExecAction(iface);
1853 TRACE("%p,%p\n", iface, directory);
1855 if (!directory) return E_POINTER;
1857 if (!action->directory) *directory = NULL;
1858 else if (!(*directory = SysAllocString(action->directory))) return E_OUTOFMEMORY;
1860 return S_OK;
1863 static HRESULT WINAPI ExecAction_put_WorkingDirectory(IExecAction *iface, BSTR directory)
1865 ExecAction *action = impl_from_IExecAction(iface);
1866 WCHAR *str = NULL;
1868 TRACE("%p,%s\n", iface, debugstr_w(directory));
1870 if (directory && !(str = heap_strdupW((directory)))) return E_OUTOFMEMORY;
1871 heap_free(action->directory);
1872 action->directory = str;
1874 return S_OK;
1877 static const IExecActionVtbl Action_vtbl =
1879 ExecAction_QueryInterface,
1880 ExecAction_AddRef,
1881 ExecAction_Release,
1882 ExecAction_GetTypeInfoCount,
1883 ExecAction_GetTypeInfo,
1884 ExecAction_GetIDsOfNames,
1885 ExecAction_Invoke,
1886 ExecAction_get_Id,
1887 ExecAction_put_Id,
1888 ExecAction_get_Type,
1889 ExecAction_get_Path,
1890 ExecAction_put_Path,
1891 ExecAction_get_Arguments,
1892 ExecAction_put_Arguments,
1893 ExecAction_get_WorkingDirectory,
1894 ExecAction_put_WorkingDirectory
1897 static HRESULT ExecAction_create(IExecAction **obj)
1899 ExecAction *action;
1901 action = heap_alloc(sizeof(*action));
1902 if (!action) return E_OUTOFMEMORY;
1904 action->IExecAction_iface.lpVtbl = &Action_vtbl;
1905 action->ref = 1;
1906 action->path = NULL;
1907 action->directory = NULL;
1908 action->args = NULL;
1909 action->id = NULL;
1911 *obj = &action->IExecAction_iface;
1913 TRACE("created %p\n", *obj);
1915 return S_OK;
1918 typedef struct
1920 IActionCollection IActionCollection_iface;
1921 LONG ref;
1922 } Actions;
1924 static inline Actions *impl_from_IActionCollection(IActionCollection *iface)
1926 return CONTAINING_RECORD(iface, Actions, IActionCollection_iface);
1929 static ULONG WINAPI Actions_AddRef(IActionCollection *iface)
1931 Actions *actions = impl_from_IActionCollection(iface);
1932 return InterlockedIncrement(&actions->ref);
1935 static ULONG WINAPI Actions_Release(IActionCollection *iface)
1937 Actions *actions = impl_from_IActionCollection(iface);
1938 LONG ref = InterlockedDecrement(&actions->ref);
1940 if (!ref)
1942 TRACE("destroying %p\n", iface);
1943 heap_free(actions);
1946 return ref;
1949 static HRESULT WINAPI Actions_QueryInterface(IActionCollection *iface, REFIID riid, void **obj)
1951 if (!riid || !obj) return E_INVALIDARG;
1953 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1955 if (IsEqualGUID(riid, &IID_IActionCollection) ||
1956 IsEqualGUID(riid, &IID_IDispatch) ||
1957 IsEqualGUID(riid, &IID_IUnknown))
1959 IActionCollection_AddRef(iface);
1960 *obj = iface;
1961 return S_OK;
1964 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1965 *obj = NULL;
1966 return E_NOINTERFACE;
1969 static HRESULT WINAPI Actions_GetTypeInfoCount(IActionCollection *iface, UINT *count)
1971 FIXME("%p,%p: stub\n", iface, count);
1972 return E_NOTIMPL;
1975 static HRESULT WINAPI Actions_GetTypeInfo(IActionCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
1977 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1978 return E_NOTIMPL;
1981 static HRESULT WINAPI Actions_GetIDsOfNames(IActionCollection *iface, REFIID riid, LPOLESTR *names,
1982 UINT count, LCID lcid, DISPID *dispid)
1984 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1985 return E_NOTIMPL;
1988 static HRESULT WINAPI Actions_Invoke(IActionCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1989 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1991 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1992 params, result, excepinfo, argerr);
1993 return E_NOTIMPL;
1996 static HRESULT WINAPI Actions_get_Count(IActionCollection *iface, LONG *count)
1998 FIXME("%p,%p: stub\n", iface, count);
1999 return E_NOTIMPL;
2002 static HRESULT WINAPI Actions_get_Item(IActionCollection *iface, LONG index, IAction **action)
2004 FIXME("%p,%d,%p: stub\n", iface, index, action);
2005 return E_NOTIMPL;
2008 static HRESULT WINAPI Actions_get__NewEnum(IActionCollection *iface, IUnknown **penum)
2010 FIXME("%p,%p: stub\n", iface, penum);
2011 return E_NOTIMPL;
2014 static HRESULT WINAPI Actions_get_XmlText(IActionCollection *iface, BSTR *xml)
2016 FIXME("%p,%p: stub\n", iface, xml);
2017 return E_NOTIMPL;
2020 static HRESULT WINAPI Actions_put_XmlText(IActionCollection *iface, BSTR xml)
2022 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
2023 return E_NOTIMPL;
2026 static HRESULT WINAPI Actions_Create(IActionCollection *iface, TASK_ACTION_TYPE type, IAction **action)
2028 TRACE("%p,%u,%p\n", iface, type, action);
2030 switch (type)
2032 case TASK_ACTION_EXEC:
2033 return ExecAction_create((IExecAction **)action);
2035 default:
2036 FIXME("unimplemented type %u\n", type);
2037 return E_NOTIMPL;
2041 static HRESULT WINAPI Actions_Remove(IActionCollection *iface, VARIANT index)
2043 FIXME("%p,%s: stub\n", iface, debugstr_variant(&index));
2044 return E_NOTIMPL;
2047 static HRESULT WINAPI Actions_Clear(IActionCollection *iface)
2049 FIXME("%p: stub\n", iface);
2050 return E_NOTIMPL;
2053 static HRESULT WINAPI Actions_get_Context(IActionCollection *iface, BSTR *ctx)
2055 FIXME("%p,%p: stub\n", iface, ctx);
2056 return E_NOTIMPL;
2059 static HRESULT WINAPI Actions_put_Context(IActionCollection *iface, BSTR ctx)
2061 FIXME("%p,%s: stub\n", iface, debugstr_w(ctx));
2062 return S_OK;
2065 static const IActionCollectionVtbl Actions_vtbl =
2067 Actions_QueryInterface,
2068 Actions_AddRef,
2069 Actions_Release,
2070 Actions_GetTypeInfoCount,
2071 Actions_GetTypeInfo,
2072 Actions_GetIDsOfNames,
2073 Actions_Invoke,
2074 Actions_get_Count,
2075 Actions_get_Item,
2076 Actions_get__NewEnum,
2077 Actions_get_XmlText,
2078 Actions_put_XmlText,
2079 Actions_Create,
2080 Actions_Remove,
2081 Actions_Clear,
2082 Actions_get_Context,
2083 Actions_put_Context
2086 static HRESULT Actions_create(IActionCollection **obj)
2088 Actions *actions;
2090 actions = heap_alloc(sizeof(*actions));
2091 if (!actions) return E_OUTOFMEMORY;
2093 actions->IActionCollection_iface.lpVtbl = &Actions_vtbl;
2094 actions->ref = 1;
2096 *obj = &actions->IActionCollection_iface;
2098 TRACE("created %p\n", *obj);
2100 return S_OK;
2103 typedef struct
2105 ITaskDefinition ITaskDefinition_iface;
2106 LONG ref;
2107 IRegistrationInfo *reginfo;
2108 ITaskSettings *taskset;
2109 ITriggerCollection *triggers;
2110 IPrincipal *principal;
2111 IActionCollection *actions;
2112 } TaskDefinition;
2114 static inline TaskDefinition *impl_from_ITaskDefinition(ITaskDefinition *iface)
2116 return CONTAINING_RECORD(iface, TaskDefinition, ITaskDefinition_iface);
2119 static ULONG WINAPI TaskDefinition_AddRef(ITaskDefinition *iface)
2121 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2122 return InterlockedIncrement(&taskdef->ref);
2125 static ULONG WINAPI TaskDefinition_Release(ITaskDefinition *iface)
2127 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2128 LONG ref = InterlockedDecrement(&taskdef->ref);
2130 if (!ref)
2132 TRACE("destroying %p\n", iface);
2134 if (taskdef->reginfo)
2135 IRegistrationInfo_Release(taskdef->reginfo);
2136 if (taskdef->taskset)
2137 ITaskSettings_Release(taskdef->taskset);
2138 if (taskdef->triggers)
2139 ITriggerCollection_Release(taskdef->triggers);
2140 if (taskdef->principal)
2141 IPrincipal_Release(taskdef->principal);
2142 if (taskdef->actions)
2143 IActionCollection_Release(taskdef->actions);
2145 heap_free(taskdef);
2148 return ref;
2151 static HRESULT WINAPI TaskDefinition_QueryInterface(ITaskDefinition *iface, REFIID riid, void **obj)
2153 if (!riid || !obj) return E_INVALIDARG;
2155 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
2157 if (IsEqualGUID(riid, &IID_ITaskDefinition) ||
2158 IsEqualGUID(riid, &IID_IDispatch) ||
2159 IsEqualGUID(riid, &IID_IUnknown))
2161 ITaskDefinition_AddRef(iface);
2162 *obj = iface;
2163 return S_OK;
2166 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
2167 *obj = NULL;
2168 return E_NOINTERFACE;
2171 static HRESULT WINAPI TaskDefinition_GetTypeInfoCount(ITaskDefinition *iface, UINT *count)
2173 FIXME("%p,%p: stub\n", iface, count);
2174 return E_NOTIMPL;
2177 static HRESULT WINAPI TaskDefinition_GetTypeInfo(ITaskDefinition *iface, UINT index, LCID lcid, ITypeInfo **info)
2179 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
2180 return E_NOTIMPL;
2183 static HRESULT WINAPI TaskDefinition_GetIDsOfNames(ITaskDefinition *iface, REFIID riid, LPOLESTR *names,
2184 UINT count, LCID lcid, DISPID *dispid)
2186 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
2187 return E_NOTIMPL;
2190 static HRESULT WINAPI TaskDefinition_Invoke(ITaskDefinition *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
2191 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
2193 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
2194 params, result, excepinfo, argerr);
2195 return E_NOTIMPL;
2198 static HRESULT WINAPI TaskDefinition_get_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo **info)
2200 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2201 HRESULT hr;
2203 TRACE("%p,%p\n", iface, info);
2205 if (!info) return E_POINTER;
2207 if (!taskdef->reginfo)
2209 hr = RegistrationInfo_create(&taskdef->reginfo);
2210 if (hr != S_OK) return hr;
2213 IRegistrationInfo_AddRef(taskdef->reginfo);
2214 *info = taskdef->reginfo;
2216 return S_OK;
2219 static HRESULT WINAPI TaskDefinition_put_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo *info)
2221 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2223 TRACE("%p,%p\n", iface, info);
2225 if (!info) return E_POINTER;
2227 if (taskdef->reginfo)
2228 IRegistrationInfo_Release(taskdef->reginfo);
2230 IRegistrationInfo_AddRef(info);
2231 taskdef->reginfo = info;
2233 return S_OK;
2236 static HRESULT WINAPI TaskDefinition_get_Triggers(ITaskDefinition *iface, ITriggerCollection **triggers)
2238 TaskDefinition *This = impl_from_ITaskDefinition(iface);
2240 TRACE("%p,%p\n", This, triggers);
2242 if (!This->triggers)
2244 trigger_collection *collection;
2246 collection = heap_alloc(sizeof(*collection));
2247 if (!collection) return E_OUTOFMEMORY;
2249 collection->ITriggerCollection_iface.lpVtbl = &TriggerCollection_vtbl;
2250 collection->ref = 1;
2251 This->triggers = &collection->ITriggerCollection_iface;
2254 ITriggerCollection_AddRef(*triggers = This->triggers);
2255 return S_OK;
2258 static HRESULT WINAPI TaskDefinition_put_Triggers(ITaskDefinition *iface, ITriggerCollection *triggers)
2260 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2262 TRACE("%p,%p\n", iface, triggers);
2264 if (!triggers) return E_POINTER;
2266 if (taskdef->triggers)
2267 ITriggerCollection_Release(taskdef->triggers);
2269 ITriggerCollection_AddRef(triggers);
2270 taskdef->triggers = triggers;
2272 return S_OK;
2275 static HRESULT WINAPI TaskDefinition_get_Settings(ITaskDefinition *iface, ITaskSettings **settings)
2277 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2278 HRESULT hr;
2280 TRACE("%p,%p\n", iface, settings);
2282 if (!settings) return E_POINTER;
2284 if (!taskdef->taskset)
2286 hr = TaskSettings_create(&taskdef->taskset);
2287 if (hr != S_OK) return hr;
2290 ITaskSettings_AddRef(taskdef->taskset);
2291 *settings = taskdef->taskset;
2293 return S_OK;
2296 static HRESULT WINAPI TaskDefinition_put_Settings(ITaskDefinition *iface, ITaskSettings *settings)
2298 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2300 TRACE("%p,%p\n", iface, settings);
2302 if (!settings) return E_POINTER;
2304 if (taskdef->taskset)
2305 ITaskSettings_Release(taskdef->taskset);
2307 ITaskSettings_AddRef(settings);
2308 taskdef->taskset = settings;
2310 return S_OK;
2313 static HRESULT WINAPI TaskDefinition_get_Data(ITaskDefinition *iface, BSTR *data)
2315 FIXME("%p,%p: stub\n", iface, data);
2316 return E_NOTIMPL;
2319 static HRESULT WINAPI TaskDefinition_put_Data(ITaskDefinition *iface, BSTR data)
2321 FIXME("%p,%p: stub\n", iface, data);
2322 return E_NOTIMPL;
2325 static HRESULT WINAPI TaskDefinition_get_Principal(ITaskDefinition *iface, IPrincipal **principal)
2327 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2328 HRESULT hr;
2330 TRACE("%p,%p\n", iface, principal);
2332 if (!principal) return E_POINTER;
2334 if (!taskdef->principal)
2336 hr = Principal_create(&taskdef->principal);
2337 if (hr != S_OK) return hr;
2340 IPrincipal_AddRef(taskdef->principal);
2341 *principal = taskdef->principal;
2343 return S_OK;
2346 static HRESULT WINAPI TaskDefinition_put_Principal(ITaskDefinition *iface, IPrincipal *principal)
2348 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2350 TRACE("%p,%p\n", iface, principal);
2352 if (!principal) return E_POINTER;
2354 if (taskdef->principal)
2355 IPrincipal_Release(taskdef->principal);
2357 IPrincipal_AddRef(principal);
2358 taskdef->principal = principal;
2360 return S_OK;
2363 static HRESULT WINAPI TaskDefinition_get_Actions(ITaskDefinition *iface, IActionCollection **actions)
2365 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2366 HRESULT hr;
2368 TRACE("%p,%p\n", iface, actions);
2370 if (!actions) return E_POINTER;
2372 if (!taskdef->actions)
2374 hr = Actions_create(&taskdef->actions);
2375 if (hr != S_OK) return hr;
2378 IActionCollection_AddRef(taskdef->actions);
2379 *actions = taskdef->actions;
2381 return S_OK;
2384 static HRESULT WINAPI TaskDefinition_put_Actions(ITaskDefinition *iface, IActionCollection *actions)
2386 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2388 TRACE("%p,%p\n", iface, actions);
2390 if (!actions) return E_POINTER;
2392 if (taskdef->actions)
2393 IActionCollection_Release(taskdef->actions);
2395 IActionCollection_AddRef(actions);
2396 taskdef->actions = actions;
2398 return S_OK;
2401 static const WCHAR Task[] = {'T','a','s','k',0};
2402 static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
2403 static const WCHAR v1_0[] = {'1','.','0',0};
2404 static const WCHAR v1_1[] = {'1','.','1',0};
2405 static const WCHAR v1_2[] = {'1','.','2',0};
2406 static const WCHAR v1_3[] = {'1','.','3',0};
2407 static const WCHAR xmlns[] = {'x','m','l','n','s',0};
2408 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};
2409 static const WCHAR RegistrationInfo[] = {'R','e','g','i','s','t','r','a','t','i','o','n','I','n','f','o',0};
2410 static const WCHAR Author[] = {'A','u','t','h','o','r',0};
2411 static const WCHAR Description[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
2412 static const WCHAR Source[] = {'S','o','u','r','c','e',0};
2413 static const WCHAR Date[] = {'D','a','t','e',0};
2414 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
2415 static const WCHAR Documentation[] = {'D','o','c','u','m','e','n','t','a','t','i','o','n',0};
2416 static const WCHAR URI[] = {'U','R','I',0};
2417 static const WCHAR SecurityDescriptor[] = {'S','e','c','u','r','i','t','y','D','e','s','c','r','i','p','t','o','r',0};
2418 static const WCHAR Settings[] = {'S','e','t','t','i','n','g','s',0};
2419 static const WCHAR Triggers[] = {'T','r','i','g','g','e','r','s',0};
2420 static const WCHAR Principals[] = {'P','r','i','n','c','i','p','a','l','s',0};
2421 static const WCHAR principalW[] = {'P','r','i','n','c','i','p','a','l',0};
2422 static const WCHAR id[] = {'i','d',0};
2423 static const WCHAR UserId[] = {'U','s','e','r','I','d',0};
2424 static const WCHAR LogonType[] = {'L','o','g','o','n','T','y','p','e',0};
2425 static const WCHAR GroupId[] = {'G','r','o','u','p','I','d',0};
2426 static const WCHAR DisplayName[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
2427 static const WCHAR HighestAvailable[] = {'H','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
2428 static const WCHAR Password[] = {'P','a','s','s','w','o','r','d',0};
2429 static const WCHAR S4U[] = {'S','4','U',0};
2430 static const WCHAR InteractiveToken[] = {'I','n','t','e','r','a','c','t','i','v','e','T','o','k','e','n',0};
2431 static const WCHAR RunLevel[] = {'R','u','n','L','e','v','e','l',0};
2432 static const WCHAR LeastPrivilege[] = {'L','e','a','s','t','P','r','i','v','i','l','e','g','e',0};
2433 static const WCHAR actionsW[] = {'A','c','t','i','o','n','s',0};
2434 static const WCHAR Exec[] = {'E','x','e','c',0};
2435 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};
2436 static const WCHAR IgnoreNew[] = {'I','g','n','o','r','e','N','e','w',0};
2437 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};
2438 static const WCHAR AllowStartOnDemand[] = {'A','l','l','o','w','S','t','a','r','t','O','n','D','e','m','a','n','d',0};
2439 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};
2440 static const WCHAR AllowHardTerminate[] = {'A','l','l','o','w','H','a','r','d','T','e','r','m','i','n','a','t','e',0};
2441 static const WCHAR StartWhenAvailable[] = {'S','t','a','r','t','W','h','e','n','A','v','a','i','l','a','b','l','e',0};
2442 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};
2443 static const WCHAR Enabled[] = {'E','n','a','b','l','e','d',0};
2444 static const WCHAR Hidden[] = {'H','i','d','d','e','n',0};
2445 static const WCHAR RunOnlyIfIdle[] = {'R','u','n','O','n','l','y','I','f','I','d','l','e',0};
2446 static const WCHAR WakeToRun[] = {'W','a','k','e','T','o','R','u','n',0};
2447 static const WCHAR ExecutionTimeLimit[] = {'E','x','e','c','u','t','i','o','n','T','i','m','e','L','i','m','i','t',0};
2448 static const WCHAR Priority[] = {'P','r','i','o','r','i','t','y',0};
2449 static const WCHAR IdleSettings[] = {'I','d','l','e','S','e','t','t','i','n','g','s',0};
2451 static int xml_indent;
2453 static inline void push_indent(void)
2455 xml_indent += 2;
2458 static inline void pop_indent(void)
2460 xml_indent -= 2;
2463 static inline HRESULT write_stringW(IStream *stream, const WCHAR *str)
2465 return IStream_Write(stream, str, lstrlenW(str) * sizeof(WCHAR), NULL);
2468 static void write_indent(IStream *stream)
2470 static const WCHAR spacesW[] = {' ',' ',0};
2471 int i;
2472 for (i = 0; i < xml_indent; i += 2)
2473 write_stringW(stream, spacesW);
2476 static const WCHAR start_element[] = {'<',0};
2477 static const WCHAR start_end_element[] = {'<','/',0};
2478 static const WCHAR close_element[] = {'>',0};
2479 static const WCHAR end_empty_element[] = {'/','>',0};
2480 static const WCHAR eol[] = {'\n',0};
2481 static const WCHAR spaceW[] = {' ',0};
2482 static const WCHAR equalW[] = {'=',0};
2483 static const WCHAR quoteW[] = {'"',0};
2485 static inline HRESULT write_empty_element(IStream *stream, const WCHAR *name)
2487 write_indent(stream);
2488 write_stringW(stream, start_element);
2489 write_stringW(stream, name);
2490 write_stringW(stream, end_empty_element);
2491 return write_stringW(stream, eol);
2494 static inline HRESULT write_element(IStream *stream, const WCHAR *name)
2496 write_indent(stream);
2497 write_stringW(stream, start_element);
2498 write_stringW(stream, name);
2499 write_stringW(stream, close_element);
2500 return write_stringW(stream, eol);
2503 static inline HRESULT write_element_end(IStream *stream, const WCHAR *name)
2505 write_indent(stream);
2506 write_stringW(stream, start_end_element);
2507 write_stringW(stream, name);
2508 write_stringW(stream, close_element);
2509 return write_stringW(stream, eol);
2512 static inline HRESULT write_text_value(IStream *stream, const WCHAR *name, const WCHAR *value)
2514 write_indent(stream);
2515 write_stringW(stream, start_element);
2516 write_stringW(stream, name);
2517 write_stringW(stream, close_element);
2518 write_stringW(stream, value);
2519 write_stringW(stream, start_end_element);
2520 write_stringW(stream, name);
2521 write_stringW(stream, close_element);
2522 return write_stringW(stream, eol);
2525 static HRESULT write_task_attributes(IStream *stream, ITaskDefinition *taskdef)
2527 HRESULT hr;
2528 ITaskSettings *taskset;
2529 TASK_COMPATIBILITY level;
2530 const WCHAR *compatibility;
2532 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
2533 if (hr != S_OK) return hr;
2535 hr = ITaskSettings_get_Compatibility(taskset, &level);
2536 if (hr != S_OK) level = TASK_COMPATIBILITY_V2_1;
2538 ITaskSettings_Release(taskset);
2540 switch (level)
2542 case TASK_COMPATIBILITY_AT:
2543 compatibility = v1_0;
2544 break;
2545 case TASK_COMPATIBILITY_V1:
2546 compatibility = v1_1;
2547 break;
2548 case TASK_COMPATIBILITY_V2:
2549 compatibility = v1_2;
2550 break;
2551 default:
2552 compatibility = v1_3;
2553 break;
2556 write_stringW(stream, start_element);
2557 write_stringW(stream, Task);
2558 write_stringW(stream, spaceW);
2559 write_stringW(stream, version);
2560 write_stringW(stream, equalW);
2561 write_stringW(stream, quoteW);
2562 write_stringW(stream, compatibility);
2563 write_stringW(stream, quoteW);
2564 write_stringW(stream, spaceW);
2565 write_stringW(stream, xmlns);
2566 write_stringW(stream, equalW);
2567 write_stringW(stream, quoteW);
2568 write_stringW(stream, task_ns);
2569 write_stringW(stream, quoteW);
2570 write_stringW(stream, close_element);
2571 return write_stringW(stream, eol);
2574 static HRESULT write_registration_info(IStream *stream, IRegistrationInfo *reginfo)
2576 HRESULT hr;
2577 BSTR bstr;
2578 VARIANT var;
2580 if (!reginfo)
2581 return write_empty_element(stream, RegistrationInfo);
2583 hr = write_element(stream, RegistrationInfo);
2584 if (hr != S_OK) return hr;
2586 push_indent();
2588 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
2589 if (hr == S_OK && bstr)
2591 hr = write_text_value(stream, Source, bstr);
2592 SysFreeString(bstr);
2593 if (hr != S_OK) return hr;
2595 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
2596 if (hr == S_OK && bstr)
2598 hr = write_text_value(stream, Date, bstr);
2599 SysFreeString(bstr);
2600 if (hr != S_OK) return hr;
2602 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
2603 if (hr == S_OK && bstr)
2605 hr = write_text_value(stream, Author, bstr);
2606 SysFreeString(bstr);
2607 if (hr != S_OK) return hr;
2609 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
2610 if (hr == S_OK && bstr)
2612 hr = write_text_value(stream, Version, bstr);
2613 SysFreeString(bstr);
2614 if (hr != S_OK) return hr;
2616 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
2617 if (hr == S_OK && bstr)
2619 hr = write_text_value(stream, Description, bstr);
2620 SysFreeString(bstr);
2621 if (hr != S_OK) return hr;
2623 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
2624 if (hr == S_OK && bstr)
2626 hr = write_text_value(stream, Documentation, bstr);
2627 SysFreeString(bstr);
2628 if (hr != S_OK) return hr;
2630 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
2631 if (hr == S_OK && bstr)
2633 hr = write_text_value(stream, URI, bstr);
2634 SysFreeString(bstr);
2635 if (hr != S_OK) return hr;
2637 hr = IRegistrationInfo_get_SecurityDescriptor(reginfo, &var);
2638 if (hr == S_OK)
2640 if (V_VT(&var) == VT_BSTR)
2642 hr = write_text_value(stream, SecurityDescriptor, V_BSTR(&var));
2643 VariantClear(&var);
2644 if (hr != S_OK) return hr;
2646 else
2647 FIXME("SecurityInfo variant type %d is not supported\n", V_VT(&var));
2650 pop_indent();
2652 return write_element_end(stream, RegistrationInfo);
2655 static HRESULT write_principal(IStream *stream, IPrincipal *principal)
2657 HRESULT hr;
2658 BSTR bstr;
2659 TASK_LOGON_TYPE logon;
2660 TASK_RUNLEVEL_TYPE level;
2662 if (!principal)
2663 return write_empty_element(stream, Principals);
2665 hr = write_element(stream, Principals);
2666 if (hr != S_OK) return hr;
2668 push_indent();
2670 hr = IPrincipal_get_Id(principal, &bstr);
2671 if (hr == S_OK)
2673 write_indent(stream);
2674 write_stringW(stream, start_element);
2675 write_stringW(stream, principalW);
2676 write_stringW(stream, spaceW);
2677 write_stringW(stream, id);
2678 write_stringW(stream, equalW);
2679 write_stringW(stream, quoteW);
2680 write_stringW(stream, bstr);
2681 write_stringW(stream, quoteW);
2682 write_stringW(stream, close_element);
2683 write_stringW(stream, eol);
2684 SysFreeString(bstr);
2686 else
2687 write_element(stream, principalW);
2689 push_indent();
2691 hr = IPrincipal_get_GroupId(principal, &bstr);
2692 if (hr == S_OK)
2694 hr = write_text_value(stream, GroupId, bstr);
2695 SysFreeString(bstr);
2696 if (hr != S_OK) return hr;
2698 hr = IPrincipal_get_DisplayName(principal, &bstr);
2699 if (hr == S_OK)
2701 hr = write_text_value(stream, DisplayName, bstr);
2702 SysFreeString(bstr);
2703 if (hr != S_OK) return hr;
2705 hr = IPrincipal_get_UserId(principal, &bstr);
2706 if (hr == S_OK && lstrlenW(bstr))
2708 hr = write_text_value(stream, UserId, bstr);
2709 SysFreeString(bstr);
2710 if (hr != S_OK) return hr;
2712 hr = IPrincipal_get_RunLevel(principal, &level);
2713 if (hr == S_OK)
2715 const WCHAR *level_str = NULL;
2717 switch (level)
2719 case TASK_RUNLEVEL_HIGHEST:
2720 level_str = HighestAvailable;
2721 break;
2722 case TASK_RUNLEVEL_LUA:
2723 level_str = LeastPrivilege;
2724 break;
2725 default:
2726 FIXME("Principal run level %d\n", level);
2727 break;
2730 if (level_str)
2732 hr = write_text_value(stream, RunLevel, level_str);
2733 if (hr != S_OK) return hr;
2736 hr = IPrincipal_get_LogonType(principal, &logon);
2737 if (hr == S_OK)
2739 const WCHAR *logon_str = NULL;
2741 switch (logon)
2743 case TASK_LOGON_PASSWORD:
2744 logon_str = Password;
2745 break;
2746 case TASK_LOGON_S4U:
2747 logon_str = S4U;
2748 break;
2749 case TASK_LOGON_INTERACTIVE_TOKEN:
2750 logon_str = InteractiveToken;
2751 break;
2752 default:
2753 FIXME("Principal logon type %d\n", logon);
2754 break;
2757 if (logon_str)
2759 hr = write_text_value(stream, LogonType, logon_str);
2760 if (hr != S_OK) return hr;
2764 pop_indent();
2765 write_element_end(stream, principalW);
2767 pop_indent();
2768 return write_element_end(stream, Principals);
2771 static HRESULT write_settings(IStream *stream, ITaskSettings *settings)
2773 if (!settings)
2774 return write_empty_element(stream, Settings);
2776 FIXME("stub\n");
2777 return S_OK;
2780 static HRESULT write_triggers(IStream *stream, ITriggerCollection *triggers)
2782 if (!triggers)
2783 return write_empty_element(stream, Triggers);
2785 FIXME("stub\n");
2786 return S_OK;
2789 static HRESULT write_actions(IStream *stream, IActionCollection *actions)
2791 if (!actions)
2793 write_element(stream, actionsW);
2794 push_indent();
2795 write_empty_element(stream, Exec);
2796 pop_indent();
2797 return write_element_end(stream, actionsW);
2800 FIXME("stub\n");
2801 return S_OK;
2804 static HRESULT WINAPI TaskDefinition_get_XmlText(ITaskDefinition *iface, BSTR *xml)
2806 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2807 HRESULT hr;
2808 IStream *stream;
2809 HGLOBAL hmem;
2810 void *p;
2812 TRACE("%p,%p\n", iface, xml);
2814 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16);
2815 if (!hmem) return E_OUTOFMEMORY;
2817 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2818 if (hr != S_OK)
2820 GlobalFree(hmem);
2821 return hr;
2824 hr = write_task_attributes(stream, &taskdef->ITaskDefinition_iface);
2825 if (hr != S_OK) goto failed;
2827 push_indent();
2829 hr = write_registration_info(stream, taskdef->reginfo);
2830 if (hr != S_OK) goto failed;
2832 hr = write_triggers(stream, taskdef->triggers);
2833 if (hr != S_OK) goto failed;
2835 hr = write_principal(stream, taskdef->principal);
2836 if (hr != S_OK) goto failed;
2838 hr = write_settings(stream, taskdef->taskset);
2839 if (hr != S_OK) goto failed;
2841 hr = write_actions(stream, taskdef->actions);
2842 if (hr != S_OK) goto failed;
2844 pop_indent();
2846 write_element_end(stream, Task);
2847 IStream_Write(stream, "\0\0", 2, NULL);
2849 p = GlobalLock(hmem);
2850 *xml = SysAllocString(p);
2851 GlobalUnlock(hmem);
2853 IStream_Release(stream);
2855 return *xml ? S_OK : E_OUTOFMEMORY;
2857 failed:
2858 IStream_Release(stream);
2859 return hr;
2862 static HRESULT read_text_value(IXmlReader *reader, WCHAR **value)
2864 HRESULT hr;
2865 XmlNodeType type;
2867 while (IXmlReader_Read(reader, &type) == S_OK)
2869 switch (type)
2871 case XmlNodeType_Text:
2872 hr = IXmlReader_GetValue(reader, (const WCHAR **)value, NULL);
2873 if (hr != S_OK) return hr;
2874 TRACE("%s\n", debugstr_w(*value));
2875 return S_OK;
2877 case XmlNodeType_Whitespace:
2878 case XmlNodeType_Comment:
2879 break;
2881 default:
2882 FIXME("unexpected node type %d\n", type);
2883 return E_FAIL;
2887 return E_FAIL;
2890 static HRESULT read_variantbool_value(IXmlReader *reader, VARIANT_BOOL *vbool)
2892 static const WCHAR trueW[] = {'t','r','u','e',0};
2893 static const WCHAR falseW[] = {'f','a','l','s','e',0};
2894 HRESULT hr;
2895 WCHAR *value;
2897 hr = read_text_value(reader, &value);
2898 if (hr != S_OK) return hr;
2900 if (!lstrcmpW(value, trueW))
2901 *vbool = VARIANT_TRUE;
2902 else if (!lstrcmpW(value, falseW))
2903 *vbool = VARIANT_FALSE;
2904 else
2906 WARN("unexpected bool value %s\n", debugstr_w(value));
2907 return SCHED_E_INVALIDVALUE;
2910 return S_OK;
2913 static HRESULT read_int_value(IXmlReader *reader, int *int_val)
2915 HRESULT hr;
2916 WCHAR *value;
2918 hr = read_text_value(reader, &value);
2919 if (hr != S_OK) return hr;
2921 *int_val = wcstol(value, NULL, 10);
2923 return S_OK;
2926 static HRESULT read_triggers(IXmlReader *reader, ITaskDefinition *taskdef)
2928 FIXME("stub\n");
2929 return S_OK;
2932 static HRESULT read_principal_attributes(IXmlReader *reader, IPrincipal *principal)
2934 HRESULT hr;
2935 const WCHAR *name;
2936 const WCHAR *value;
2938 hr = IXmlReader_MoveToFirstAttribute(reader);
2940 while (hr == S_OK)
2942 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2943 if (hr != S_OK) break;
2945 hr = IXmlReader_GetValue(reader, &value, NULL);
2946 if (hr != S_OK) break;
2948 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
2950 if (!lstrcmpW(name, id))
2951 IPrincipal_put_Id(principal, (BSTR)value);
2952 else
2953 FIXME("unhandled Principal attribute %s\n", debugstr_w(name));
2955 hr = IXmlReader_MoveToNextAttribute(reader);
2958 return S_OK;
2961 static HRESULT read_principal(IXmlReader *reader, IPrincipal *principal)
2963 HRESULT hr;
2964 XmlNodeType type;
2965 const WCHAR *name;
2966 WCHAR *value;
2968 if (IXmlReader_IsEmptyElement(reader))
2970 TRACE("Principal is empty\n");
2971 return S_OK;
2974 read_principal_attributes(reader, principal);
2976 while (IXmlReader_Read(reader, &type) == S_OK)
2978 switch (type)
2980 case XmlNodeType_EndElement:
2981 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2982 if (hr != S_OK) return hr;
2984 TRACE("/%s\n", debugstr_w(name));
2986 if (!lstrcmpW(name, principalW))
2987 return S_OK;
2989 break;
2991 case XmlNodeType_Element:
2992 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2993 if (hr != S_OK) return hr;
2995 TRACE("Element: %s\n", debugstr_w(name));
2997 if (!lstrcmpW(name, UserId))
2999 hr = read_text_value(reader, &value);
3000 if (hr == S_OK)
3001 IPrincipal_put_UserId(principal, value);
3003 else if (!lstrcmpW(name, LogonType))
3005 hr = read_text_value(reader, &value);
3006 if (hr == S_OK)
3008 TASK_LOGON_TYPE logon = TASK_LOGON_NONE;
3010 if (!lstrcmpW(value, InteractiveToken))
3011 logon = TASK_LOGON_INTERACTIVE_TOKEN;
3012 else
3013 FIXME("unhandled LogonType %s\n", debugstr_w(value));
3015 IPrincipal_put_LogonType(principal, logon);
3018 else if (!lstrcmpW(name, RunLevel))
3020 hr = read_text_value(reader, &value);
3021 if (hr == S_OK)
3023 TASK_RUNLEVEL_TYPE level = TASK_RUNLEVEL_LUA;
3025 if (!lstrcmpW(value, LeastPrivilege))
3026 level = TASK_RUNLEVEL_LUA;
3027 else
3028 FIXME("unhandled RunLevel %s\n", debugstr_w(value));
3030 IPrincipal_put_RunLevel(principal, level);
3033 else
3034 FIXME("unhandled Principal element %s\n", debugstr_w(name));
3036 break;
3038 case XmlNodeType_Whitespace:
3039 case XmlNodeType_Comment:
3040 break;
3042 default:
3043 FIXME("unhandled Principal node type %d\n", type);
3044 break;
3048 WARN("Principal was not terminated\n");
3049 return E_FAIL;
3052 static HRESULT read_principals(IXmlReader *reader, ITaskDefinition *taskdef)
3054 HRESULT hr;
3055 XmlNodeType type;
3056 const WCHAR *name;
3058 if (IXmlReader_IsEmptyElement(reader))
3060 TRACE("Principals is empty\n");
3061 return S_OK;
3064 while (IXmlReader_Read(reader, &type) == S_OK)
3066 switch (type)
3068 case XmlNodeType_EndElement:
3069 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3070 if (hr != S_OK) return hr;
3072 TRACE("/%s\n", debugstr_w(name));
3074 if (!lstrcmpW(name, Principals))
3075 return S_OK;
3077 break;
3079 case XmlNodeType_Element:
3080 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3081 if (hr != S_OK) return hr;
3083 TRACE("Element: %s\n", debugstr_w(name));
3085 if (!lstrcmpW(name, principalW))
3087 IPrincipal *principal;
3089 hr = ITaskDefinition_get_Principal(taskdef, &principal);
3090 if (hr != S_OK) return hr;
3091 hr = read_principal(reader, principal);
3092 IPrincipal_Release(principal);
3094 else
3095 FIXME("unhandled Principals element %s\n", debugstr_w(name));
3097 break;
3099 case XmlNodeType_Whitespace:
3100 case XmlNodeType_Comment:
3101 break;
3103 default:
3104 FIXME("unhandled Principals node type %d\n", type);
3105 break;
3109 WARN("Principals was not terminated\n");
3110 return E_FAIL;
3113 static HRESULT read_actions(IXmlReader *reader, ITaskDefinition *taskdef)
3115 FIXME("stub\n");
3116 return S_OK;
3119 static HRESULT read_idle_settings(IXmlReader *reader, ITaskSettings *taskset)
3121 FIXME("stub\n");
3122 return S_OK;
3125 static HRESULT read_settings(IXmlReader *reader, ITaskSettings *taskset)
3127 HRESULT hr;
3128 XmlNodeType type;
3129 const WCHAR *name;
3130 WCHAR *value;
3131 VARIANT_BOOL bool_val;
3132 int int_val;
3134 if (IXmlReader_IsEmptyElement(reader))
3136 TRACE("Settings is empty\n");
3137 return S_OK;
3140 while (IXmlReader_Read(reader, &type) == S_OK)
3142 switch (type)
3144 case XmlNodeType_EndElement:
3145 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3146 if (hr != S_OK) return hr;
3148 TRACE("/%s\n", debugstr_w(name));
3150 if (!lstrcmpW(name, Settings))
3151 return S_OK;
3153 break;
3155 case XmlNodeType_Element:
3156 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3157 if (hr != S_OK) return hr;
3159 TRACE("Element: %s\n", debugstr_w(name));
3161 if (!lstrcmpW(name, MultipleInstancesPolicy))
3163 hr = read_text_value(reader, &value);
3164 if (hr == S_OK)
3166 int_val = TASK_INSTANCES_IGNORE_NEW;
3168 if (!lstrcmpW(value, IgnoreNew))
3169 int_val = TASK_INSTANCES_IGNORE_NEW;
3170 else
3171 FIXME("unhandled MultipleInstancesPolicy %s\n", debugstr_w(value));
3173 ITaskSettings_put_MultipleInstances(taskset, int_val);
3176 else if (!lstrcmpW(name, DisallowStartIfOnBatteries))
3178 hr = read_variantbool_value(reader, &bool_val);
3179 if (hr != S_OK) return hr;
3180 ITaskSettings_put_DisallowStartIfOnBatteries(taskset, bool_val);
3182 else if (!lstrcmpW(name, AllowStartOnDemand))
3184 hr = read_variantbool_value(reader, &bool_val);
3185 if (hr != S_OK) return hr;
3186 ITaskSettings_put_AllowDemandStart(taskset, bool_val);
3188 else if (!lstrcmpW(name, StopIfGoingOnBatteries))
3190 hr = read_variantbool_value(reader, &bool_val);
3191 if (hr != S_OK) return hr;
3192 ITaskSettings_put_StopIfGoingOnBatteries(taskset, bool_val);
3194 else if (!lstrcmpW(name, AllowHardTerminate))
3196 hr = read_variantbool_value(reader, &bool_val);
3197 if (hr != S_OK) return hr;
3198 ITaskSettings_put_AllowHardTerminate(taskset, bool_val);
3200 else if (!lstrcmpW(name, StartWhenAvailable))
3202 hr = read_variantbool_value(reader, &bool_val);
3203 if (hr != S_OK) return hr;
3204 ITaskSettings_put_StartWhenAvailable(taskset, bool_val);
3206 else if (!lstrcmpW(name, RunOnlyIfNetworkAvailable))
3208 hr = read_variantbool_value(reader, &bool_val);
3209 if (hr != S_OK) return hr;
3210 ITaskSettings_put_RunOnlyIfNetworkAvailable(taskset, bool_val);
3212 else if (!lstrcmpW(name, Enabled))
3214 hr = read_variantbool_value(reader, &bool_val);
3215 if (hr != S_OK) return hr;
3216 ITaskSettings_put_Enabled(taskset, bool_val);
3218 else if (!lstrcmpW(name, Hidden))
3220 hr = read_variantbool_value(reader, &bool_val);
3221 if (hr != S_OK) return hr;
3222 ITaskSettings_put_Hidden(taskset, bool_val);
3224 else if (!lstrcmpW(name, RunOnlyIfIdle))
3226 hr = read_variantbool_value(reader, &bool_val);
3227 if (hr != S_OK) return hr;
3228 ITaskSettings_put_RunOnlyIfIdle(taskset, bool_val);
3230 else if (!lstrcmpW(name, WakeToRun))
3232 hr = read_variantbool_value(reader, &bool_val);
3233 if (hr != S_OK) return hr;
3234 ITaskSettings_put_WakeToRun(taskset, bool_val);
3236 else if (!lstrcmpW(name, ExecutionTimeLimit))
3238 hr = read_text_value(reader, &value);
3239 if (hr == S_OK)
3240 ITaskSettings_put_ExecutionTimeLimit(taskset, value);
3242 else if (!lstrcmpW(name, Priority))
3244 hr = read_int_value(reader, &int_val);
3245 if (hr == S_OK)
3246 ITaskSettings_put_Priority(taskset, int_val);
3248 else if (!lstrcmpW(name, IdleSettings))
3250 hr = read_idle_settings(reader, taskset);
3251 if (hr != S_OK) return hr;
3253 else
3254 FIXME("unhandled Settings element %s\n", debugstr_w(name));
3256 break;
3258 case XmlNodeType_Whitespace:
3259 case XmlNodeType_Comment:
3260 break;
3262 default:
3263 FIXME("unhandled Settings node type %d\n", type);
3264 break;
3268 WARN("Settings was not terminated\n");
3269 return SCHED_E_MALFORMEDXML;
3272 static HRESULT read_registration_info(IXmlReader *reader, IRegistrationInfo *info)
3274 HRESULT hr;
3275 XmlNodeType type;
3276 const WCHAR *name;
3277 WCHAR *value;
3279 if (IXmlReader_IsEmptyElement(reader))
3281 TRACE("RegistrationInfo is empty\n");
3282 return S_OK;
3285 while (IXmlReader_Read(reader, &type) == S_OK)
3287 switch (type)
3289 case XmlNodeType_EndElement:
3290 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3291 if (hr != S_OK) return hr;
3293 TRACE("/%s\n", debugstr_w(name));
3295 if (!lstrcmpW(name, RegistrationInfo))
3296 return S_OK;
3298 break;
3300 case XmlNodeType_Element:
3301 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3302 if (hr != S_OK) return hr;
3304 TRACE("Element: %s\n", debugstr_w(name));
3306 if (!lstrcmpW(name, Author))
3308 hr = read_text_value(reader, &value);
3309 if (hr == S_OK)
3310 IRegistrationInfo_put_Author(info, value);
3312 else if (!lstrcmpW(name, Description))
3314 hr = read_text_value(reader, &value);
3315 if (hr == S_OK)
3316 IRegistrationInfo_put_Description(info, value);
3318 else if (!lstrcmpW(name, Version))
3320 hr = read_text_value(reader, &value);
3321 if (hr == S_OK)
3322 IRegistrationInfo_put_Version(info, value);
3324 else if (!lstrcmpW(name, Date))
3326 hr = read_text_value(reader, &value);
3327 if (hr == S_OK)
3328 IRegistrationInfo_put_Date(info, value);
3330 else if (!lstrcmpW(name, Documentation))
3332 hr = read_text_value(reader, &value);
3333 if (hr == S_OK)
3334 IRegistrationInfo_put_Documentation(info, value);
3336 else if (!lstrcmpW(name, URI))
3338 hr = read_text_value(reader, &value);
3339 if (hr == S_OK)
3340 IRegistrationInfo_put_URI(info, value);
3342 else if (!lstrcmpW(name, Source))
3344 hr = read_text_value(reader, &value);
3345 if (hr == S_OK)
3346 IRegistrationInfo_put_Source(info, value);
3348 else
3349 FIXME("unhandled RegistrationInfo element %s\n", debugstr_w(name));
3351 break;
3353 case XmlNodeType_Whitespace:
3354 case XmlNodeType_Comment:
3355 break;
3357 default:
3358 FIXME("unhandled RegistrationInfo node type %d\n", type);
3359 break;
3363 WARN("RegistrationInfo was not terminated\n");
3364 return SCHED_E_MALFORMEDXML;
3367 static HRESULT read_task_attributes(IXmlReader *reader, ITaskDefinition *taskdef)
3369 HRESULT hr;
3370 ITaskSettings *taskset;
3371 const WCHAR *name;
3372 const WCHAR *value;
3373 BOOL xmlns_ok = FALSE;
3375 TRACE("\n");
3377 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3378 if (hr != S_OK) return hr;
3380 hr = IXmlReader_MoveToFirstAttribute(reader);
3382 while (hr == S_OK)
3384 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3385 if (hr != S_OK) break;
3387 hr = IXmlReader_GetValue(reader, &value, NULL);
3388 if (hr != S_OK) break;
3390 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
3392 if (!lstrcmpW(name, version))
3394 TASK_COMPATIBILITY compatibility = TASK_COMPATIBILITY_V2;
3396 if (!lstrcmpW(value, v1_0))
3397 compatibility = TASK_COMPATIBILITY_AT;
3398 else if (!lstrcmpW(value, v1_1))
3399 compatibility = TASK_COMPATIBILITY_V1;
3400 else if (!lstrcmpW(value, v1_2))
3401 compatibility = TASK_COMPATIBILITY_V2;
3402 else if (!lstrcmpW(value, v1_3))
3403 compatibility = TASK_COMPATIBILITY_V2_1;
3404 else
3405 FIXME("unknown version %s\n", debugstr_w(value));
3407 ITaskSettings_put_Compatibility(taskset, compatibility);
3409 else if (!lstrcmpW(name, xmlns))
3411 if (lstrcmpW(value, task_ns))
3413 FIXME("unknown namespace %s\n", debugstr_w(value));
3414 break;
3416 xmlns_ok = TRUE;
3418 else
3419 FIXME("unhandled Task attribute %s\n", debugstr_w(name));
3421 hr = IXmlReader_MoveToNextAttribute(reader);
3424 ITaskSettings_Release(taskset);
3425 return xmlns_ok ? S_OK : SCHED_E_NAMESPACE;
3428 static HRESULT read_task(IXmlReader *reader, ITaskDefinition *taskdef)
3430 HRESULT hr;
3431 XmlNodeType type;
3432 const WCHAR *name;
3434 if (IXmlReader_IsEmptyElement(reader))
3436 TRACE("Task is empty\n");
3437 return S_OK;
3440 while (IXmlReader_Read(reader, &type) == S_OK)
3442 switch (type)
3444 case XmlNodeType_EndElement:
3445 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3446 if (hr != S_OK) return hr;
3448 TRACE("/%s\n", debugstr_w(name));
3450 if (!lstrcmpW(name, Task))
3451 return S_OK;
3453 break;
3455 case XmlNodeType_Element:
3456 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3457 if (hr != S_OK) return hr;
3459 TRACE("Element: %s\n", debugstr_w(name));
3461 if (!lstrcmpW(name, RegistrationInfo))
3463 IRegistrationInfo *info;
3465 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &info);
3466 if (hr != S_OK) return hr;
3467 hr = read_registration_info(reader, info);
3468 IRegistrationInfo_Release(info);
3470 else if (!lstrcmpW(name, Settings))
3472 ITaskSettings *taskset;
3474 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3475 if (hr != S_OK) return hr;
3476 hr = read_settings(reader, taskset);
3477 ITaskSettings_Release(taskset);
3479 else if (!lstrcmpW(name, Triggers))
3480 hr = read_triggers(reader, taskdef);
3481 else if (!lstrcmpW(name, Principals))
3482 hr = read_principals(reader, taskdef);
3483 else if (!lstrcmpW(name, actionsW))
3484 hr = read_actions(reader, taskdef);
3485 else
3486 FIXME("unhandled Task element %s\n", debugstr_w(name));
3488 if (hr != S_OK) return hr;
3489 break;
3491 case XmlNodeType_Comment:
3492 case XmlNodeType_Whitespace:
3493 break;
3495 default:
3496 FIXME("unhandled Task node type %d\n", type);
3497 break;
3501 WARN("Task was not terminated\n");
3502 return SCHED_E_MALFORMEDXML;
3505 static HRESULT read_xml(IXmlReader *reader, ITaskDefinition *taskdef)
3507 HRESULT hr;
3508 XmlNodeType type;
3509 const WCHAR *name;
3511 while (IXmlReader_Read(reader, &type) == S_OK)
3513 switch (type)
3515 case XmlNodeType_XmlDeclaration:
3516 TRACE("XmlDeclaration\n");
3517 break;
3519 case XmlNodeType_Element:
3520 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3521 if (hr != S_OK) return hr;
3523 TRACE("Element: %s\n", debugstr_w(name));
3525 if (!lstrcmpW(name, Task))
3527 hr = read_task_attributes(reader, taskdef);
3528 if (hr != S_OK) return hr;
3530 return read_task(reader, taskdef);
3532 else
3533 FIXME("unhandled XML element %s\n", debugstr_w(name));
3535 break;
3537 case XmlNodeType_Comment:
3538 case XmlNodeType_Whitespace:
3539 break;
3541 default:
3542 FIXME("unhandled XML node type %d\n", type);
3543 break;
3547 WARN("Task definition was not found\n");
3548 return SCHED_E_MALFORMEDXML;
3551 static HRESULT WINAPI TaskDefinition_put_XmlText(ITaskDefinition *iface, BSTR xml)
3553 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
3554 HRESULT hr;
3555 IStream *stream;
3556 IXmlReader *reader;
3557 HGLOBAL hmem;
3558 void *buf;
3560 TRACE("%p,%s\n", iface, debugstr_w(xml));
3562 if (!xml) return E_INVALIDARG;
3564 hmem = GlobalAlloc(0, lstrlenW(xml) * sizeof(WCHAR));
3565 if (!hmem) return E_OUTOFMEMORY;
3567 buf = GlobalLock(hmem);
3568 memcpy(buf, xml, lstrlenW(xml) * sizeof(WCHAR));
3569 GlobalUnlock(hmem);
3571 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
3572 if (hr != S_OK)
3574 GlobalFree(hmem);
3575 return hr;
3578 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
3579 if (hr != S_OK)
3581 IStream_Release(stream);
3582 return hr;
3585 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
3586 if (hr == S_OK)
3588 if (taskdef->reginfo)
3590 IRegistrationInfo_Release(taskdef->reginfo);
3591 taskdef->reginfo = NULL;
3593 if (taskdef->taskset)
3595 ITaskSettings_Release(taskdef->taskset);
3596 taskdef->taskset = NULL;
3598 if (taskdef->triggers)
3600 ITriggerCollection_Release(taskdef->triggers);
3601 taskdef->triggers = NULL;
3603 if (taskdef->principal)
3605 IPrincipal_Release(taskdef->principal);
3606 taskdef->principal = NULL;
3608 if (taskdef->actions)
3610 IActionCollection_Release(taskdef->actions);
3611 taskdef->actions = NULL;
3614 hr = read_xml(reader, iface);
3617 IXmlReader_Release(reader);
3618 IStream_Release(stream);
3620 return hr;
3623 static const ITaskDefinitionVtbl TaskDefinition_vtbl =
3625 TaskDefinition_QueryInterface,
3626 TaskDefinition_AddRef,
3627 TaskDefinition_Release,
3628 TaskDefinition_GetTypeInfoCount,
3629 TaskDefinition_GetTypeInfo,
3630 TaskDefinition_GetIDsOfNames,
3631 TaskDefinition_Invoke,
3632 TaskDefinition_get_RegistrationInfo,
3633 TaskDefinition_put_RegistrationInfo,
3634 TaskDefinition_get_Triggers,
3635 TaskDefinition_put_Triggers,
3636 TaskDefinition_get_Settings,
3637 TaskDefinition_put_Settings,
3638 TaskDefinition_get_Data,
3639 TaskDefinition_put_Data,
3640 TaskDefinition_get_Principal,
3641 TaskDefinition_put_Principal,
3642 TaskDefinition_get_Actions,
3643 TaskDefinition_put_Actions,
3644 TaskDefinition_get_XmlText,
3645 TaskDefinition_put_XmlText
3648 HRESULT TaskDefinition_create(ITaskDefinition **obj)
3650 TaskDefinition *taskdef;
3652 taskdef = heap_alloc_zero(sizeof(*taskdef));
3653 if (!taskdef) return E_OUTOFMEMORY;
3655 taskdef->ITaskDefinition_iface.lpVtbl = &TaskDefinition_vtbl;
3656 taskdef->ref = 1;
3657 *obj = &taskdef->ITaskDefinition_iface;
3659 TRACE("created %p\n", *obj);
3661 return S_OK;
3664 typedef struct
3666 ITaskService ITaskService_iface;
3667 LONG ref;
3668 BOOL connected;
3669 DWORD version;
3670 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3671 } TaskService;
3673 static inline TaskService *impl_from_ITaskService(ITaskService *iface)
3675 return CONTAINING_RECORD(iface, TaskService, ITaskService_iface);
3678 static ULONG WINAPI TaskService_AddRef(ITaskService *iface)
3680 TaskService *task_svc = impl_from_ITaskService(iface);
3681 return InterlockedIncrement(&task_svc->ref);
3684 static ULONG WINAPI TaskService_Release(ITaskService *iface)
3686 TaskService *task_svc = impl_from_ITaskService(iface);
3687 LONG ref = InterlockedDecrement(&task_svc->ref);
3689 if (!ref)
3691 TRACE("destroying %p\n", iface);
3692 heap_free(task_svc);
3695 return ref;
3698 static HRESULT WINAPI TaskService_QueryInterface(ITaskService *iface, REFIID riid, void **obj)
3700 if (!riid || !obj) return E_INVALIDARG;
3702 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
3704 if (IsEqualGUID(riid, &IID_ITaskService) ||
3705 IsEqualGUID(riid, &IID_IDispatch) ||
3706 IsEqualGUID(riid, &IID_IUnknown))
3708 ITaskService_AddRef(iface);
3709 *obj = iface;
3710 return S_OK;
3713 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
3714 *obj = NULL;
3715 return E_NOINTERFACE;
3718 static HRESULT WINAPI TaskService_GetTypeInfoCount(ITaskService *iface, UINT *count)
3720 FIXME("%p,%p: stub\n", iface, count);
3721 return E_NOTIMPL;
3724 static HRESULT WINAPI TaskService_GetTypeInfo(ITaskService *iface, UINT index, LCID lcid, ITypeInfo **info)
3726 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
3727 return E_NOTIMPL;
3730 static HRESULT WINAPI TaskService_GetIDsOfNames(ITaskService *iface, REFIID riid, LPOLESTR *names,
3731 UINT count, LCID lcid, DISPID *dispid)
3733 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
3734 return E_NOTIMPL;
3737 static HRESULT WINAPI TaskService_Invoke(ITaskService *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
3738 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
3740 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
3741 params, result, excepinfo, argerr);
3742 return E_NOTIMPL;
3745 static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITaskFolder **folder)
3747 TaskService *task_svc = impl_from_ITaskService(iface);
3749 TRACE("%p,%s,%p\n", iface, debugstr_w(path), folder);
3751 if (!folder) return E_POINTER;
3753 if (!task_svc->connected)
3754 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3756 return TaskFolder_create(path, NULL, folder, FALSE);
3759 static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks)
3761 FIXME("%p,%x,%p: stub\n", iface, flags, tasks);
3762 return E_NOTIMPL;
3765 static HRESULT WINAPI TaskService_NewTask(ITaskService *iface, DWORD flags, ITaskDefinition **definition)
3767 TRACE("%p,%x,%p\n", iface, flags, definition);
3769 if (!definition) return E_POINTER;
3771 if (flags)
3772 FIXME("unsupported flags %x\n", flags);
3774 return TaskDefinition_create(definition);
3777 static inline BOOL is_variant_null(const VARIANT *var)
3779 return V_VT(var) == VT_EMPTY || V_VT(var) == VT_NULL ||
3780 (V_VT(var) == VT_BSTR && (V_BSTR(var) == NULL || !*V_BSTR(var)));
3783 static HRESULT start_schedsvc(void)
3785 static const WCHAR scheduleW[] = { 'S','c','h','e','d','u','l','e',0 };
3786 SC_HANDLE scm, service;
3787 SERVICE_STATUS_PROCESS status;
3788 ULONGLONG start_time;
3789 HRESULT hr = SCHED_E_SERVICE_NOT_RUNNING;
3791 TRACE("Trying to start %s service\n", debugstr_w(scheduleW));
3793 scm = OpenSCManagerW(NULL, NULL, 0);
3794 if (!scm) return SCHED_E_SERVICE_NOT_INSTALLED;
3796 service = OpenServiceW(scm, scheduleW, SERVICE_START | SERVICE_QUERY_STATUS);
3797 if (service)
3799 if (StartServiceW(service, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
3801 start_time = GetTickCount64();
3804 DWORD dummy;
3806 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(status), &dummy))
3808 WARN("failed to query scheduler status (%u)\n", GetLastError());
3809 break;
3812 if (status.dwCurrentState == SERVICE_RUNNING)
3814 hr = S_OK;
3815 break;
3818 if (GetTickCount64() - start_time > 30000) break;
3819 Sleep(1000);
3821 } while (status.dwCurrentState == SERVICE_START_PENDING);
3823 if (status.dwCurrentState != SERVICE_RUNNING)
3824 WARN("scheduler failed to start %u\n", status.dwCurrentState);
3826 else
3827 WARN("failed to start scheduler service (%u)\n", GetLastError());
3829 CloseServiceHandle(service);
3831 else
3832 WARN("failed to open scheduler service (%u)\n", GetLastError());
3834 CloseServiceHandle(scm);
3835 return hr;
3838 static HRESULT WINAPI TaskService_Connect(ITaskService *iface, VARIANT server, VARIANT user, VARIANT domain, VARIANT password)
3840 static WCHAR ncalrpc[] = { 'n','c','a','l','r','p','c',0 };
3841 TaskService *task_svc = impl_from_ITaskService(iface);
3842 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3843 DWORD len;
3844 HRESULT hr;
3845 RPC_WSTR binding_str;
3846 extern handle_t schrpc_handle;
3848 TRACE("%p,%s,%s,%s,%s\n", iface, debugstr_variant(&server), debugstr_variant(&user),
3849 debugstr_variant(&domain), debugstr_variant(&password));
3851 if (!is_variant_null(&user) || !is_variant_null(&domain) || !is_variant_null(&password))
3852 FIXME("user/domain/password are ignored\n");
3854 len = ARRAY_SIZE(comp_name);
3855 if (!GetComputerNameW(comp_name, &len))
3856 return HRESULT_FROM_WIN32(GetLastError());
3858 if (!is_variant_null(&server))
3860 const WCHAR *server_name;
3862 if (V_VT(&server) != VT_BSTR)
3864 FIXME("server variant type %d is not supported\n", V_VT(&server));
3865 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3868 /* skip UNC prefix if any */
3869 server_name = V_BSTR(&server);
3870 if (server_name[0] == '\\' && server_name[1] == '\\')
3871 server_name += 2;
3873 if (wcsicmp(server_name, comp_name))
3875 FIXME("connection to remote server %s is not supported\n", debugstr_w(V_BSTR(&server)));
3876 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3880 hr = start_schedsvc();
3881 if (hr != S_OK) return hr;
3883 hr = RpcStringBindingComposeW(NULL, ncalrpc, NULL, NULL, NULL, &binding_str);
3884 if (hr != RPC_S_OK) return hr;
3885 hr = RpcBindingFromStringBindingW(binding_str, &schrpc_handle);
3886 RpcStringFreeW(&binding_str);
3887 if (hr != RPC_S_OK) return hr;
3889 /* Make sure that the connection works */
3890 hr = SchRpcHighestVersion(&task_svc->version);
3891 if (hr != S_OK) return hr;
3893 TRACE("server version %#x\n", task_svc->version);
3895 lstrcpyW(task_svc->comp_name, comp_name);
3896 task_svc->connected = TRUE;
3898 return S_OK;
3901 static HRESULT WINAPI TaskService_get_Connected(ITaskService *iface, VARIANT_BOOL *connected)
3903 TaskService *task_svc = impl_from_ITaskService(iface);
3905 TRACE("%p,%p\n", iface, connected);
3907 if (!connected) return E_POINTER;
3909 *connected = task_svc->connected ? VARIANT_TRUE : VARIANT_FALSE;
3911 return S_OK;
3914 static HRESULT WINAPI TaskService_get_TargetServer(ITaskService *iface, BSTR *server)
3916 TaskService *task_svc = impl_from_ITaskService(iface);
3918 TRACE("%p,%p\n", iface, server);
3920 if (!server) return E_POINTER;
3922 if (!task_svc->connected)
3923 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3925 *server = SysAllocString(task_svc->comp_name);
3926 if (!*server) return E_OUTOFMEMORY;
3928 return S_OK;
3931 static HRESULT WINAPI TaskService_get_ConnectedUser(ITaskService *iface, BSTR *user)
3933 FIXME("%p,%p: stub\n", iface, user);
3934 return E_NOTIMPL;
3937 static HRESULT WINAPI TaskService_get_ConnectedDomain(ITaskService *iface, BSTR *domain)
3939 FIXME("%p,%p: stub\n", iface, domain);
3940 return E_NOTIMPL;
3943 static HRESULT WINAPI TaskService_get_HighestVersion(ITaskService *iface, DWORD *version)
3945 TaskService *task_svc = impl_from_ITaskService(iface);
3947 TRACE("%p,%p\n", iface, version);
3949 if (!version) return E_POINTER;
3951 if (!task_svc->connected)
3952 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3954 *version = task_svc->version;
3956 return S_OK;
3959 static const ITaskServiceVtbl TaskService_vtbl =
3961 TaskService_QueryInterface,
3962 TaskService_AddRef,
3963 TaskService_Release,
3964 TaskService_GetTypeInfoCount,
3965 TaskService_GetTypeInfo,
3966 TaskService_GetIDsOfNames,
3967 TaskService_Invoke,
3968 TaskService_GetFolder,
3969 TaskService_GetRunningTasks,
3970 TaskService_NewTask,
3971 TaskService_Connect,
3972 TaskService_get_Connected,
3973 TaskService_get_TargetServer,
3974 TaskService_get_ConnectedUser,
3975 TaskService_get_ConnectedDomain,
3976 TaskService_get_HighestVersion
3979 HRESULT TaskService_create(void **obj)
3981 TaskService *task_svc;
3983 task_svc = heap_alloc(sizeof(*task_svc));
3984 if (!task_svc) return E_OUTOFMEMORY;
3986 task_svc->ITaskService_iface.lpVtbl = &TaskService_vtbl;
3987 task_svc->ref = 1;
3988 task_svc->connected = FALSE;
3989 *obj = &task_svc->ITaskService_iface;
3991 TRACE("created %p\n", *obj);
3993 return S_OK;
3996 void __RPC_FAR *__RPC_USER MIDL_user_allocate(SIZE_T n)
3998 return HeapAlloc(GetProcessHeap(), 0, n);
4001 void __RPC_USER MIDL_user_free(void __RPC_FAR *p)
4003 HeapFree(GetProcessHeap(), 0, p);