dinput: Enumerate user format object forwards.
[wine.git] / dlls / taskschd / task.c
blob28c0ff899458528601fa5a67f541392f4ee92444
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=%ld\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=%ld\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 %lu %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 %lu %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)->(%ld %s %lx %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=%ld\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=%ld\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 %lu %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 %lu %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)->(%ld %s %lx %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)->(%ld %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,%lu,%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,%lu,%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,%ld,%s,%04lx,%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,%lu,%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,%lu,%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,%ld,%s,%04lx,%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 TaskSettings *taskset;
1445 taskset = heap_alloc(sizeof(*taskset));
1446 if (!taskset) return E_OUTOFMEMORY;
1448 taskset->ITaskSettings_iface.lpVtbl = &TaskSettings_vtbl;
1449 taskset->ref = 1;
1450 /* set the defaults */
1451 taskset->restart_interval = NULL;
1452 taskset->execution_time_limit = heap_strdupW(L"PT72H");
1453 taskset->delete_expired_task_after = NULL;
1454 taskset->restart_count = 0;
1455 taskset->priority = 7;
1456 taskset->policy = TASK_INSTANCES_IGNORE_NEW;
1457 taskset->compatibility = TASK_COMPATIBILITY_V2;
1458 taskset->allow_on_demand_start = TRUE;
1459 taskset->stop_if_going_on_batteries = TRUE;
1460 taskset->disallow_start_if_on_batteries = TRUE;
1461 taskset->allow_hard_terminate = TRUE;
1462 taskset->start_when_available = FALSE;
1463 taskset->run_only_if_network_available = FALSE;
1464 taskset->enabled = TRUE;
1465 taskset->hidden = FALSE;
1466 taskset->run_only_if_idle = FALSE;
1467 taskset->wake_to_run = FALSE;
1469 *obj = &taskset->ITaskSettings_iface;
1471 TRACE("created %p\n", *obj);
1473 return S_OK;
1476 typedef struct
1478 IPrincipal IPrincipal_iface;
1479 LONG ref;
1480 } Principal;
1482 static inline Principal *impl_from_IPrincipal(IPrincipal *iface)
1484 return CONTAINING_RECORD(iface, Principal, IPrincipal_iface);
1487 static ULONG WINAPI Principal_AddRef(IPrincipal *iface)
1489 Principal *principal = impl_from_IPrincipal(iface);
1490 return InterlockedIncrement(&principal->ref);
1493 static ULONG WINAPI Principal_Release(IPrincipal *iface)
1495 Principal *principal = impl_from_IPrincipal(iface);
1496 LONG ref = InterlockedDecrement(&principal->ref);
1498 if (!ref)
1500 TRACE("destroying %p\n", iface);
1501 heap_free(principal);
1504 return ref;
1507 static HRESULT WINAPI Principal_QueryInterface(IPrincipal *iface, REFIID riid, void **obj)
1509 if (!riid || !obj) return E_INVALIDARG;
1511 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1513 if (IsEqualGUID(riid, &IID_IPrincipal) ||
1514 IsEqualGUID(riid, &IID_IDispatch) ||
1515 IsEqualGUID(riid, &IID_IUnknown))
1517 IPrincipal_AddRef(iface);
1518 *obj = iface;
1519 return S_OK;
1522 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1523 *obj = NULL;
1524 return E_NOINTERFACE;
1527 static HRESULT WINAPI Principal_GetTypeInfoCount(IPrincipal *iface, UINT *count)
1529 FIXME("%p,%p: stub\n", iface, count);
1530 return E_NOTIMPL;
1533 static HRESULT WINAPI Principal_GetTypeInfo(IPrincipal *iface, UINT index, LCID lcid, ITypeInfo **info)
1535 FIXME("%p,%u,%lu,%p: stub\n", iface, index, lcid, info);
1536 return E_NOTIMPL;
1539 static HRESULT WINAPI Principal_GetIDsOfNames(IPrincipal *iface, REFIID riid, LPOLESTR *names,
1540 UINT count, LCID lcid, DISPID *dispid)
1542 FIXME("%p,%s,%p,%u,%lu,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1543 return E_NOTIMPL;
1546 static HRESULT WINAPI Principal_Invoke(IPrincipal *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1547 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1549 FIXME("%p,%ld,%s,%04lx,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1550 params, result, excepinfo, argerr);
1551 return E_NOTIMPL;
1554 static HRESULT WINAPI Principal_get_Id(IPrincipal *iface, BSTR *id)
1556 FIXME("%p,%p: stub\n", iface, id);
1557 return E_NOTIMPL;
1560 static HRESULT WINAPI Principal_put_Id(IPrincipal *iface, BSTR id)
1562 FIXME("%p,%s: stub\n", iface, debugstr_w(id));
1563 return S_OK;
1566 static HRESULT WINAPI Principal_get_DisplayName(IPrincipal *iface, BSTR *name)
1568 FIXME("%p,%p: stub\n", iface, name);
1569 return E_NOTIMPL;
1572 static HRESULT WINAPI Principal_put_DisplayName(IPrincipal *iface, BSTR name)
1574 FIXME("%p,%s: stub\n", iface, debugstr_w(name));
1575 return E_NOTIMPL;
1578 static HRESULT WINAPI Principal_get_UserId(IPrincipal *iface, BSTR *user_id)
1580 FIXME("%p,%p: stub\n", iface, user_id);
1581 return E_NOTIMPL;
1584 static HRESULT WINAPI Principal_put_UserId(IPrincipal *iface, BSTR user_id)
1586 FIXME("%p,%s: stub\n", iface, debugstr_w(user_id));
1587 return S_OK;
1590 static HRESULT WINAPI Principal_get_LogonType(IPrincipal *iface, TASK_LOGON_TYPE *logon_type)
1592 FIXME("%p,%p: stub\n", iface, logon_type);
1593 return E_NOTIMPL;
1596 static HRESULT WINAPI Principal_put_LogonType(IPrincipal *iface, TASK_LOGON_TYPE logon_type)
1598 FIXME("%p,%u: stub\n", iface, logon_type);
1599 return E_NOTIMPL;
1602 static HRESULT WINAPI Principal_get_GroupId(IPrincipal *iface, BSTR *group_id)
1604 FIXME("%p,%p: stub\n", iface, group_id);
1605 return E_NOTIMPL;
1608 static HRESULT WINAPI Principal_put_GroupId(IPrincipal *iface, BSTR group_id)
1610 FIXME("%p,%s: stub\n", iface, debugstr_w(group_id));
1611 return E_NOTIMPL;
1614 static HRESULT WINAPI Principal_get_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE *run_level)
1616 FIXME("%p,%p: stub\n", iface, run_level);
1617 return E_NOTIMPL;
1620 static HRESULT WINAPI Principal_put_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE run_level)
1622 FIXME("%p,%u: stub\n", iface, run_level);
1623 return E_NOTIMPL;
1626 static const IPrincipalVtbl Principal_vtbl =
1628 Principal_QueryInterface,
1629 Principal_AddRef,
1630 Principal_Release,
1631 Principal_GetTypeInfoCount,
1632 Principal_GetTypeInfo,
1633 Principal_GetIDsOfNames,
1634 Principal_Invoke,
1635 Principal_get_Id,
1636 Principal_put_Id,
1637 Principal_get_DisplayName,
1638 Principal_put_DisplayName,
1639 Principal_get_UserId,
1640 Principal_put_UserId,
1641 Principal_get_LogonType,
1642 Principal_put_LogonType,
1643 Principal_get_GroupId,
1644 Principal_put_GroupId,
1645 Principal_get_RunLevel,
1646 Principal_put_RunLevel
1649 static HRESULT Principal_create(IPrincipal **obj)
1651 Principal *principal;
1653 principal = heap_alloc(sizeof(*principal));
1654 if (!principal) return E_OUTOFMEMORY;
1656 principal->IPrincipal_iface.lpVtbl = &Principal_vtbl;
1657 principal->ref = 1;
1659 *obj = &principal->IPrincipal_iface;
1661 TRACE("created %p\n", *obj);
1663 return S_OK;
1666 typedef struct
1668 IExecAction IExecAction_iface;
1669 LONG ref;
1670 WCHAR *path;
1671 WCHAR *directory;
1672 WCHAR *args;
1673 WCHAR *id;
1674 } ExecAction;
1676 static inline ExecAction *impl_from_IExecAction(IExecAction *iface)
1678 return CONTAINING_RECORD(iface, ExecAction, IExecAction_iface);
1681 static ULONG WINAPI ExecAction_AddRef(IExecAction *iface)
1683 ExecAction *action = impl_from_IExecAction(iface);
1684 return InterlockedIncrement(&action->ref);
1687 static ULONG WINAPI ExecAction_Release(IExecAction *iface)
1689 ExecAction *action = impl_from_IExecAction(iface);
1690 LONG ref = InterlockedDecrement(&action->ref);
1692 if (!ref)
1694 TRACE("destroying %p\n", iface);
1695 heap_free(action->path);
1696 heap_free(action->directory);
1697 heap_free(action->args);
1698 heap_free(action->id);
1699 heap_free(action);
1702 return ref;
1705 static HRESULT WINAPI ExecAction_QueryInterface(IExecAction *iface, REFIID riid, void **obj)
1707 if (!riid || !obj) return E_INVALIDARG;
1709 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1711 if (IsEqualGUID(riid, &IID_IExecAction) ||
1712 IsEqualGUID(riid, &IID_IAction) ||
1713 IsEqualGUID(riid, &IID_IDispatch) ||
1714 IsEqualGUID(riid, &IID_IUnknown))
1716 IExecAction_AddRef(iface);
1717 *obj = iface;
1718 return S_OK;
1721 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1722 *obj = NULL;
1723 return E_NOINTERFACE;
1726 static HRESULT WINAPI ExecAction_GetTypeInfoCount(IExecAction *iface, UINT *count)
1728 FIXME("%p,%p: stub\n", iface, count);
1729 return E_NOTIMPL;
1732 static HRESULT WINAPI ExecAction_GetTypeInfo(IExecAction *iface, UINT index, LCID lcid, ITypeInfo **info)
1734 FIXME("%p,%u,%lu,%p: stub\n", iface, index, lcid, info);
1735 return E_NOTIMPL;
1738 static HRESULT WINAPI ExecAction_GetIDsOfNames(IExecAction *iface, REFIID riid, LPOLESTR *names,
1739 UINT count, LCID lcid, DISPID *dispid)
1741 FIXME("%p,%s,%p,%u,%lu,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1742 return E_NOTIMPL;
1745 static HRESULT WINAPI ExecAction_Invoke(IExecAction *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1746 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1748 FIXME("%p,%ld,%s,%04lx,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1749 params, result, excepinfo, argerr);
1750 return E_NOTIMPL;
1753 static HRESULT WINAPI ExecAction_get_Id(IExecAction *iface, BSTR *id)
1755 ExecAction *action = impl_from_IExecAction(iface);
1757 TRACE("%p,%p\n", iface, id);
1759 if (!id) return E_POINTER;
1761 if (!action->id) *id = NULL;
1762 else if (!(*id = SysAllocString(action->id))) return E_OUTOFMEMORY;
1764 return S_OK;
1767 static HRESULT WINAPI ExecAction_put_Id(IExecAction *iface, BSTR id)
1769 ExecAction *action = impl_from_IExecAction(iface);
1770 WCHAR *str = NULL;
1772 TRACE("%p,%s\n", iface, debugstr_w(id));
1774 if (id && !(str = heap_strdupW((id)))) return E_OUTOFMEMORY;
1775 heap_free(action->id);
1776 action->id = str;
1778 return S_OK;
1781 static HRESULT WINAPI ExecAction_get_Type(IExecAction *iface, TASK_ACTION_TYPE *type)
1783 TRACE("%p,%p\n", iface, type);
1785 if (!type) return E_POINTER;
1787 *type = TASK_ACTION_EXEC;
1789 return S_OK;
1792 static HRESULT WINAPI ExecAction_get_Path(IExecAction *iface, BSTR *path)
1794 ExecAction *action = impl_from_IExecAction(iface);
1796 TRACE("%p,%p\n", iface, path);
1798 if (!path) return E_POINTER;
1800 if (!action->path) *path = NULL;
1801 else if (!(*path = SysAllocString(action->path))) return E_OUTOFMEMORY;
1803 return S_OK;
1806 static HRESULT WINAPI ExecAction_put_Path(IExecAction *iface, BSTR path)
1808 ExecAction *action = impl_from_IExecAction(iface);
1809 WCHAR *str = NULL;
1811 TRACE("%p,%s\n", iface, debugstr_w(path));
1813 if (path && !(str = heap_strdupW((path)))) return E_OUTOFMEMORY;
1814 heap_free(action->path);
1815 action->path = str;
1817 return S_OK;
1820 static HRESULT WINAPI ExecAction_get_Arguments(IExecAction *iface, BSTR *arguments)
1822 ExecAction *action = impl_from_IExecAction(iface);
1824 TRACE("%p,%p\n", iface, arguments);
1826 if (!arguments) return E_POINTER;
1828 if (!action->args) *arguments = NULL;
1829 else if (!(*arguments = SysAllocString(action->args))) return E_OUTOFMEMORY;
1831 return S_OK;
1834 static HRESULT WINAPI ExecAction_put_Arguments(IExecAction *iface, BSTR arguments)
1836 ExecAction *action = impl_from_IExecAction(iface);
1837 WCHAR *str = NULL;
1839 TRACE("%p,%s\n", iface, debugstr_w(arguments));
1841 if (arguments && !(str = heap_strdupW((arguments)))) return E_OUTOFMEMORY;
1842 heap_free(action->args);
1843 action->args = str;
1845 return S_OK;
1848 static HRESULT WINAPI ExecAction_get_WorkingDirectory(IExecAction *iface, BSTR *directory)
1850 ExecAction *action = impl_from_IExecAction(iface);
1852 TRACE("%p,%p\n", iface, directory);
1854 if (!directory) return E_POINTER;
1856 if (!action->directory) *directory = NULL;
1857 else if (!(*directory = SysAllocString(action->directory))) return E_OUTOFMEMORY;
1859 return S_OK;
1862 static HRESULT WINAPI ExecAction_put_WorkingDirectory(IExecAction *iface, BSTR directory)
1864 ExecAction *action = impl_from_IExecAction(iface);
1865 WCHAR *str = NULL;
1867 TRACE("%p,%s\n", iface, debugstr_w(directory));
1869 if (directory && !(str = heap_strdupW((directory)))) return E_OUTOFMEMORY;
1870 heap_free(action->directory);
1871 action->directory = str;
1873 return S_OK;
1876 static const IExecActionVtbl Action_vtbl =
1878 ExecAction_QueryInterface,
1879 ExecAction_AddRef,
1880 ExecAction_Release,
1881 ExecAction_GetTypeInfoCount,
1882 ExecAction_GetTypeInfo,
1883 ExecAction_GetIDsOfNames,
1884 ExecAction_Invoke,
1885 ExecAction_get_Id,
1886 ExecAction_put_Id,
1887 ExecAction_get_Type,
1888 ExecAction_get_Path,
1889 ExecAction_put_Path,
1890 ExecAction_get_Arguments,
1891 ExecAction_put_Arguments,
1892 ExecAction_get_WorkingDirectory,
1893 ExecAction_put_WorkingDirectory
1896 static HRESULT ExecAction_create(IExecAction **obj)
1898 ExecAction *action;
1900 action = heap_alloc(sizeof(*action));
1901 if (!action) return E_OUTOFMEMORY;
1903 action->IExecAction_iface.lpVtbl = &Action_vtbl;
1904 action->ref = 1;
1905 action->path = NULL;
1906 action->directory = NULL;
1907 action->args = NULL;
1908 action->id = NULL;
1910 *obj = &action->IExecAction_iface;
1912 TRACE("created %p\n", *obj);
1914 return S_OK;
1917 typedef struct
1919 IActionCollection IActionCollection_iface;
1920 LONG ref;
1921 } Actions;
1923 static inline Actions *impl_from_IActionCollection(IActionCollection *iface)
1925 return CONTAINING_RECORD(iface, Actions, IActionCollection_iface);
1928 static ULONG WINAPI Actions_AddRef(IActionCollection *iface)
1930 Actions *actions = impl_from_IActionCollection(iface);
1931 return InterlockedIncrement(&actions->ref);
1934 static ULONG WINAPI Actions_Release(IActionCollection *iface)
1936 Actions *actions = impl_from_IActionCollection(iface);
1937 LONG ref = InterlockedDecrement(&actions->ref);
1939 if (!ref)
1941 TRACE("destroying %p\n", iface);
1942 heap_free(actions);
1945 return ref;
1948 static HRESULT WINAPI Actions_QueryInterface(IActionCollection *iface, REFIID riid, void **obj)
1950 if (!riid || !obj) return E_INVALIDARG;
1952 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1954 if (IsEqualGUID(riid, &IID_IActionCollection) ||
1955 IsEqualGUID(riid, &IID_IDispatch) ||
1956 IsEqualGUID(riid, &IID_IUnknown))
1958 IActionCollection_AddRef(iface);
1959 *obj = iface;
1960 return S_OK;
1963 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1964 *obj = NULL;
1965 return E_NOINTERFACE;
1968 static HRESULT WINAPI Actions_GetTypeInfoCount(IActionCollection *iface, UINT *count)
1970 FIXME("%p,%p: stub\n", iface, count);
1971 return E_NOTIMPL;
1974 static HRESULT WINAPI Actions_GetTypeInfo(IActionCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
1976 FIXME("%p,%u,%lu,%p: stub\n", iface, index, lcid, info);
1977 return E_NOTIMPL;
1980 static HRESULT WINAPI Actions_GetIDsOfNames(IActionCollection *iface, REFIID riid, LPOLESTR *names,
1981 UINT count, LCID lcid, DISPID *dispid)
1983 FIXME("%p,%s,%p,%u,%lu,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1984 return E_NOTIMPL;
1987 static HRESULT WINAPI Actions_Invoke(IActionCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1988 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1990 FIXME("%p,%ld,%s,%04lx,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1991 params, result, excepinfo, argerr);
1992 return E_NOTIMPL;
1995 static HRESULT WINAPI Actions_get_Count(IActionCollection *iface, LONG *count)
1997 FIXME("%p,%p: stub\n", iface, count);
1998 return E_NOTIMPL;
2001 static HRESULT WINAPI Actions_get_Item(IActionCollection *iface, LONG index, IAction **action)
2003 FIXME("%p,%ld,%p: stub\n", iface, index, action);
2004 return E_NOTIMPL;
2007 static HRESULT WINAPI Actions_get__NewEnum(IActionCollection *iface, IUnknown **penum)
2009 FIXME("%p,%p: stub\n", iface, penum);
2010 return E_NOTIMPL;
2013 static HRESULT WINAPI Actions_get_XmlText(IActionCollection *iface, BSTR *xml)
2015 FIXME("%p,%p: stub\n", iface, xml);
2016 return E_NOTIMPL;
2019 static HRESULT WINAPI Actions_put_XmlText(IActionCollection *iface, BSTR xml)
2021 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
2022 return E_NOTIMPL;
2025 static HRESULT WINAPI Actions_Create(IActionCollection *iface, TASK_ACTION_TYPE type, IAction **action)
2027 TRACE("%p,%u,%p\n", iface, type, action);
2029 switch (type)
2031 case TASK_ACTION_EXEC:
2032 return ExecAction_create((IExecAction **)action);
2034 default:
2035 FIXME("unimplemented type %u\n", type);
2036 return E_NOTIMPL;
2040 static HRESULT WINAPI Actions_Remove(IActionCollection *iface, VARIANT index)
2042 FIXME("%p,%s: stub\n", iface, debugstr_variant(&index));
2043 return E_NOTIMPL;
2046 static HRESULT WINAPI Actions_Clear(IActionCollection *iface)
2048 FIXME("%p: stub\n", iface);
2049 return E_NOTIMPL;
2052 static HRESULT WINAPI Actions_get_Context(IActionCollection *iface, BSTR *ctx)
2054 FIXME("%p,%p: stub\n", iface, ctx);
2055 return E_NOTIMPL;
2058 static HRESULT WINAPI Actions_put_Context(IActionCollection *iface, BSTR ctx)
2060 FIXME("%p,%s: stub\n", iface, debugstr_w(ctx));
2061 return S_OK;
2064 static const IActionCollectionVtbl Actions_vtbl =
2066 Actions_QueryInterface,
2067 Actions_AddRef,
2068 Actions_Release,
2069 Actions_GetTypeInfoCount,
2070 Actions_GetTypeInfo,
2071 Actions_GetIDsOfNames,
2072 Actions_Invoke,
2073 Actions_get_Count,
2074 Actions_get_Item,
2075 Actions_get__NewEnum,
2076 Actions_get_XmlText,
2077 Actions_put_XmlText,
2078 Actions_Create,
2079 Actions_Remove,
2080 Actions_Clear,
2081 Actions_get_Context,
2082 Actions_put_Context
2085 static HRESULT Actions_create(IActionCollection **obj)
2087 Actions *actions;
2089 actions = heap_alloc(sizeof(*actions));
2090 if (!actions) return E_OUTOFMEMORY;
2092 actions->IActionCollection_iface.lpVtbl = &Actions_vtbl;
2093 actions->ref = 1;
2095 *obj = &actions->IActionCollection_iface;
2097 TRACE("created %p\n", *obj);
2099 return S_OK;
2102 typedef struct
2104 ITaskDefinition ITaskDefinition_iface;
2105 LONG ref;
2106 IRegistrationInfo *reginfo;
2107 ITaskSettings *taskset;
2108 ITriggerCollection *triggers;
2109 IPrincipal *principal;
2110 IActionCollection *actions;
2111 } TaskDefinition;
2113 static inline TaskDefinition *impl_from_ITaskDefinition(ITaskDefinition *iface)
2115 return CONTAINING_RECORD(iface, TaskDefinition, ITaskDefinition_iface);
2118 static ULONG WINAPI TaskDefinition_AddRef(ITaskDefinition *iface)
2120 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2121 return InterlockedIncrement(&taskdef->ref);
2124 static ULONG WINAPI TaskDefinition_Release(ITaskDefinition *iface)
2126 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2127 LONG ref = InterlockedDecrement(&taskdef->ref);
2129 if (!ref)
2131 TRACE("destroying %p\n", iface);
2133 if (taskdef->reginfo)
2134 IRegistrationInfo_Release(taskdef->reginfo);
2135 if (taskdef->taskset)
2136 ITaskSettings_Release(taskdef->taskset);
2137 if (taskdef->triggers)
2138 ITriggerCollection_Release(taskdef->triggers);
2139 if (taskdef->principal)
2140 IPrincipal_Release(taskdef->principal);
2141 if (taskdef->actions)
2142 IActionCollection_Release(taskdef->actions);
2144 heap_free(taskdef);
2147 return ref;
2150 static HRESULT WINAPI TaskDefinition_QueryInterface(ITaskDefinition *iface, REFIID riid, void **obj)
2152 if (!riid || !obj) return E_INVALIDARG;
2154 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
2156 if (IsEqualGUID(riid, &IID_ITaskDefinition) ||
2157 IsEqualGUID(riid, &IID_IDispatch) ||
2158 IsEqualGUID(riid, &IID_IUnknown))
2160 ITaskDefinition_AddRef(iface);
2161 *obj = iface;
2162 return S_OK;
2165 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
2166 *obj = NULL;
2167 return E_NOINTERFACE;
2170 static HRESULT WINAPI TaskDefinition_GetTypeInfoCount(ITaskDefinition *iface, UINT *count)
2172 FIXME("%p,%p: stub\n", iface, count);
2173 return E_NOTIMPL;
2176 static HRESULT WINAPI TaskDefinition_GetTypeInfo(ITaskDefinition *iface, UINT index, LCID lcid, ITypeInfo **info)
2178 FIXME("%p,%u,%lu,%p: stub\n", iface, index, lcid, info);
2179 return E_NOTIMPL;
2182 static HRESULT WINAPI TaskDefinition_GetIDsOfNames(ITaskDefinition *iface, REFIID riid, LPOLESTR *names,
2183 UINT count, LCID lcid, DISPID *dispid)
2185 FIXME("%p,%s,%p,%u,%lu,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
2186 return E_NOTIMPL;
2189 static HRESULT WINAPI TaskDefinition_Invoke(ITaskDefinition *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
2190 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
2192 FIXME("%p,%ld,%s,%04lx,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
2193 params, result, excepinfo, argerr);
2194 return E_NOTIMPL;
2197 static HRESULT WINAPI TaskDefinition_get_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo **info)
2199 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2200 HRESULT hr;
2202 TRACE("%p,%p\n", iface, info);
2204 if (!info) return E_POINTER;
2206 if (!taskdef->reginfo)
2208 hr = RegistrationInfo_create(&taskdef->reginfo);
2209 if (hr != S_OK) return hr;
2212 IRegistrationInfo_AddRef(taskdef->reginfo);
2213 *info = taskdef->reginfo;
2215 return S_OK;
2218 static HRESULT WINAPI TaskDefinition_put_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo *info)
2220 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2222 TRACE("%p,%p\n", iface, info);
2224 if (!info) return E_POINTER;
2226 if (taskdef->reginfo)
2227 IRegistrationInfo_Release(taskdef->reginfo);
2229 IRegistrationInfo_AddRef(info);
2230 taskdef->reginfo = info;
2232 return S_OK;
2235 static HRESULT WINAPI TaskDefinition_get_Triggers(ITaskDefinition *iface, ITriggerCollection **triggers)
2237 TaskDefinition *This = impl_from_ITaskDefinition(iface);
2239 TRACE("%p,%p\n", This, triggers);
2241 if (!This->triggers)
2243 trigger_collection *collection;
2245 collection = heap_alloc(sizeof(*collection));
2246 if (!collection) return E_OUTOFMEMORY;
2248 collection->ITriggerCollection_iface.lpVtbl = &TriggerCollection_vtbl;
2249 collection->ref = 1;
2250 This->triggers = &collection->ITriggerCollection_iface;
2253 ITriggerCollection_AddRef(*triggers = This->triggers);
2254 return S_OK;
2257 static HRESULT WINAPI TaskDefinition_put_Triggers(ITaskDefinition *iface, ITriggerCollection *triggers)
2259 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2261 TRACE("%p,%p\n", iface, triggers);
2263 if (!triggers) return E_POINTER;
2265 if (taskdef->triggers)
2266 ITriggerCollection_Release(taskdef->triggers);
2268 ITriggerCollection_AddRef(triggers);
2269 taskdef->triggers = triggers;
2271 return S_OK;
2274 static HRESULT WINAPI TaskDefinition_get_Settings(ITaskDefinition *iface, ITaskSettings **settings)
2276 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2277 HRESULT hr;
2279 TRACE("%p,%p\n", iface, settings);
2281 if (!settings) return E_POINTER;
2283 if (!taskdef->taskset)
2285 hr = TaskSettings_create(&taskdef->taskset);
2286 if (hr != S_OK) return hr;
2289 ITaskSettings_AddRef(taskdef->taskset);
2290 *settings = taskdef->taskset;
2292 return S_OK;
2295 static HRESULT WINAPI TaskDefinition_put_Settings(ITaskDefinition *iface, ITaskSettings *settings)
2297 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2299 TRACE("%p,%p\n", iface, settings);
2301 if (!settings) return E_POINTER;
2303 if (taskdef->taskset)
2304 ITaskSettings_Release(taskdef->taskset);
2306 ITaskSettings_AddRef(settings);
2307 taskdef->taskset = settings;
2309 return S_OK;
2312 static HRESULT WINAPI TaskDefinition_get_Data(ITaskDefinition *iface, BSTR *data)
2314 FIXME("%p,%p: stub\n", iface, data);
2315 return E_NOTIMPL;
2318 static HRESULT WINAPI TaskDefinition_put_Data(ITaskDefinition *iface, BSTR data)
2320 FIXME("%p,%p: stub\n", iface, data);
2321 return E_NOTIMPL;
2324 static HRESULT WINAPI TaskDefinition_get_Principal(ITaskDefinition *iface, IPrincipal **principal)
2326 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2327 HRESULT hr;
2329 TRACE("%p,%p\n", iface, principal);
2331 if (!principal) return E_POINTER;
2333 if (!taskdef->principal)
2335 hr = Principal_create(&taskdef->principal);
2336 if (hr != S_OK) return hr;
2339 IPrincipal_AddRef(taskdef->principal);
2340 *principal = taskdef->principal;
2342 return S_OK;
2345 static HRESULT WINAPI TaskDefinition_put_Principal(ITaskDefinition *iface, IPrincipal *principal)
2347 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2349 TRACE("%p,%p\n", iface, principal);
2351 if (!principal) return E_POINTER;
2353 if (taskdef->principal)
2354 IPrincipal_Release(taskdef->principal);
2356 IPrincipal_AddRef(principal);
2357 taskdef->principal = principal;
2359 return S_OK;
2362 static HRESULT WINAPI TaskDefinition_get_Actions(ITaskDefinition *iface, IActionCollection **actions)
2364 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2365 HRESULT hr;
2367 TRACE("%p,%p\n", iface, actions);
2369 if (!actions) return E_POINTER;
2371 if (!taskdef->actions)
2373 hr = Actions_create(&taskdef->actions);
2374 if (hr != S_OK) return hr;
2377 IActionCollection_AddRef(taskdef->actions);
2378 *actions = taskdef->actions;
2380 return S_OK;
2383 static HRESULT WINAPI TaskDefinition_put_Actions(ITaskDefinition *iface, IActionCollection *actions)
2385 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2387 TRACE("%p,%p\n", iface, actions);
2389 if (!actions) return E_POINTER;
2391 if (taskdef->actions)
2392 IActionCollection_Release(taskdef->actions);
2394 IActionCollection_AddRef(actions);
2395 taskdef->actions = actions;
2397 return S_OK;
2400 static int xml_indent;
2402 static inline void push_indent(void)
2404 xml_indent += 2;
2407 static inline void pop_indent(void)
2409 xml_indent -= 2;
2412 static inline HRESULT write_stringW(IStream *stream, const WCHAR *str)
2414 return IStream_Write(stream, str, lstrlenW(str) * sizeof(WCHAR), NULL);
2417 static void write_indent(IStream *stream)
2419 int i;
2420 for (i = 0; i < xml_indent; i += 2)
2421 write_stringW(stream, L" ");
2424 static inline HRESULT write_empty_element(IStream *stream, const WCHAR *name)
2426 write_indent(stream);
2427 write_stringW(stream, L"<");
2428 write_stringW(stream, name);
2429 return write_stringW(stream, L"/>\n");
2432 static inline HRESULT write_element(IStream *stream, const WCHAR *name)
2434 write_indent(stream);
2435 write_stringW(stream, L"<");
2436 write_stringW(stream, name);
2437 return write_stringW(stream, L">\n");
2440 static inline HRESULT write_element_end(IStream *stream, const WCHAR *name)
2442 write_indent(stream);
2443 write_stringW(stream, L"</");
2444 write_stringW(stream, name);
2445 return write_stringW(stream, L">\n");
2448 static inline HRESULT write_text_value(IStream *stream, const WCHAR *name, const WCHAR *value)
2450 write_indent(stream);
2451 write_stringW(stream, L"<");
2452 write_stringW(stream, name);
2453 write_stringW(stream, L">");
2454 write_stringW(stream, value);
2455 write_stringW(stream, L"</");
2456 write_stringW(stream, name);
2457 return write_stringW(stream, L">\n");
2460 static HRESULT write_bool_value(IStream *stream, const WCHAR *name, VARIANT_BOOL value)
2462 return write_text_value(stream, name, value ? L"true" : L"false");
2465 static HRESULT write_int_value(IStream *stream, const WCHAR *name, int val)
2467 WCHAR s[32];
2469 swprintf(s, ARRAY_SIZE(s), L"%d", val);
2470 return write_text_value(stream, name, s);
2473 static HRESULT write_task_attributes(IStream *stream, ITaskDefinition *taskdef)
2475 HRESULT hr;
2476 ITaskSettings *taskset;
2477 TASK_COMPATIBILITY level;
2478 const WCHAR *compatibility;
2480 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
2481 if (hr != S_OK) return hr;
2483 hr = ITaskSettings_get_Compatibility(taskset, &level);
2484 if (hr != S_OK) level = TASK_COMPATIBILITY_V2_1;
2486 ITaskSettings_Release(taskset);
2488 switch (level)
2490 case TASK_COMPATIBILITY_AT:
2491 compatibility = L"1.0";
2492 break;
2493 case TASK_COMPATIBILITY_V1:
2494 compatibility = L"1.1";
2495 break;
2496 case TASK_COMPATIBILITY_V2:
2497 compatibility = L"1.2";
2498 break;
2499 default:
2500 compatibility = L"1.3";
2501 break;
2504 write_stringW(stream, L"<Task version=\"");
2505 write_stringW(stream, compatibility);
2506 write_stringW(stream, L"\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">");
2507 return write_stringW(stream, L"\n");
2510 static HRESULT write_registration_info(IStream *stream, IRegistrationInfo *reginfo)
2512 HRESULT hr;
2513 BSTR bstr;
2514 VARIANT var;
2516 if (!reginfo)
2517 return write_empty_element(stream, L"RegistrationInfo");
2519 hr = write_element(stream, L"RegistrationInfo");
2520 if (hr != S_OK) return hr;
2522 push_indent();
2524 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
2525 if (hr == S_OK && bstr)
2527 hr = write_text_value(stream, L"Source", bstr);
2528 SysFreeString(bstr);
2529 if (hr != S_OK) return hr;
2531 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
2532 if (hr == S_OK && bstr)
2534 hr = write_text_value(stream, L"Date", bstr);
2535 SysFreeString(bstr);
2536 if (hr != S_OK) return hr;
2538 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
2539 if (hr == S_OK && bstr)
2541 hr = write_text_value(stream, L"Author", bstr);
2542 SysFreeString(bstr);
2543 if (hr != S_OK) return hr;
2545 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
2546 if (hr == S_OK && bstr)
2548 hr = write_text_value(stream, L"Version", bstr);
2549 SysFreeString(bstr);
2550 if (hr != S_OK) return hr;
2552 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
2553 if (hr == S_OK && bstr)
2555 hr = write_text_value(stream, L"Description", bstr);
2556 SysFreeString(bstr);
2557 if (hr != S_OK) return hr;
2559 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
2560 if (hr == S_OK && bstr)
2562 hr = write_text_value(stream, L"Documentation", bstr);
2563 SysFreeString(bstr);
2564 if (hr != S_OK) return hr;
2566 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
2567 if (hr == S_OK && bstr)
2569 hr = write_text_value(stream, L"URI", bstr);
2570 SysFreeString(bstr);
2571 if (hr != S_OK) return hr;
2573 hr = IRegistrationInfo_get_SecurityDescriptor(reginfo, &var);
2574 if (hr == S_OK)
2576 if (V_VT(&var) == VT_BSTR)
2578 hr = write_text_value(stream, L"SecurityDescriptor", V_BSTR(&var));
2579 VariantClear(&var);
2580 if (hr != S_OK) return hr;
2582 else
2583 FIXME("SecurityInfo variant type %d is not supported\n", V_VT(&var));
2586 pop_indent();
2588 return write_element_end(stream, L"RegistrationInfo");
2591 static HRESULT write_principal(IStream *stream, IPrincipal *principal)
2593 HRESULT hr;
2594 BSTR bstr;
2595 TASK_LOGON_TYPE logon;
2596 TASK_RUNLEVEL_TYPE level;
2598 if (!principal)
2599 return write_empty_element(stream, L"Principals");
2601 hr = write_element(stream, L"Principals");
2602 if (hr != S_OK) return hr;
2604 push_indent();
2606 hr = IPrincipal_get_Id(principal, &bstr);
2607 if (hr == S_OK)
2609 write_indent(stream);
2610 write_stringW(stream, L"<Principal id=\"");
2611 write_stringW(stream, bstr);
2612 write_stringW(stream, L"\">\n");
2613 SysFreeString(bstr);
2615 else
2616 write_element(stream, L"Principal");
2618 push_indent();
2620 hr = IPrincipal_get_GroupId(principal, &bstr);
2621 if (hr == S_OK)
2623 hr = write_text_value(stream, L"GroupId", bstr);
2624 SysFreeString(bstr);
2625 if (hr != S_OK) return hr;
2627 hr = IPrincipal_get_DisplayName(principal, &bstr);
2628 if (hr == S_OK)
2630 hr = write_text_value(stream, L"DisplayName", bstr);
2631 SysFreeString(bstr);
2632 if (hr != S_OK) return hr;
2634 hr = IPrincipal_get_UserId(principal, &bstr);
2635 if (hr == S_OK && lstrlenW(bstr))
2637 hr = write_text_value(stream, L"UserId", bstr);
2638 SysFreeString(bstr);
2639 if (hr != S_OK) return hr;
2641 hr = IPrincipal_get_RunLevel(principal, &level);
2642 if (hr == S_OK)
2644 const WCHAR *level_str = NULL;
2646 switch (level)
2648 case TASK_RUNLEVEL_HIGHEST:
2649 level_str = L"HighestAvailable";
2650 break;
2651 case TASK_RUNLEVEL_LUA:
2652 level_str = L"LeastPrivilege";
2653 break;
2654 default:
2655 FIXME("Principal run level %d\n", level);
2656 break;
2659 if (level_str)
2661 hr = write_text_value(stream, L"RunLevel", level_str);
2662 if (hr != S_OK) return hr;
2665 hr = IPrincipal_get_LogonType(principal, &logon);
2666 if (hr == S_OK)
2668 const WCHAR *logon_str = NULL;
2670 switch (logon)
2672 case TASK_LOGON_PASSWORD:
2673 logon_str = L"Password";
2674 break;
2675 case TASK_LOGON_S4U:
2676 logon_str = L"S4U";
2677 break;
2678 case TASK_LOGON_INTERACTIVE_TOKEN:
2679 logon_str = L"InteractiveToken";
2680 break;
2681 default:
2682 FIXME("Principal logon type %d\n", logon);
2683 break;
2686 if (logon_str)
2688 hr = write_text_value(stream, L"LogonType", logon_str);
2689 if (hr != S_OK) return hr;
2693 pop_indent();
2694 write_element_end(stream, L"Principal");
2696 pop_indent();
2697 return write_element_end(stream, L"Principals");
2700 const WCHAR *string_from_instances_policy(TASK_INSTANCES_POLICY policy)
2702 switch (policy)
2704 case TASK_INSTANCES_PARALLEL: return L"Parallel";
2705 case TASK_INSTANCES_QUEUE: return L"Queue";
2706 case TASK_INSTANCES_IGNORE_NEW: return L"IgnoreNew";
2707 case TASK_INSTANCES_STOP_EXISTING : return L"StopExisting";
2709 return L"<error>";
2712 static HRESULT write_settings(IStream *stream, ITaskSettings *settings)
2714 INetworkSettings *network_settings;
2715 TASK_INSTANCES_POLICY policy;
2716 IIdleSettings *idle_settings;
2717 VARIANT_BOOL bval;
2718 HRESULT hr;
2719 INT ival;
2720 BSTR s;
2722 if (!settings)
2723 return write_empty_element(stream, L"Settings");
2725 if (FAILED(hr = write_element(stream, L"Settings")))
2726 return hr;
2728 push_indent();
2730 #define WRITE_BOOL_OPTION(name) \
2732 if (FAILED(hr = ITaskSettings_get_##name(settings, &bval))) \
2733 return hr; \
2734 if (FAILED(hr = write_bool_value(stream, L ## #name, bval))) \
2735 return hr; \
2739 if (FAILED(hr = ITaskSettings_get_AllowDemandStart(settings, &bval)))
2740 return hr;
2741 if (FAILED(hr = write_bool_value(stream, L"AllowStartOnDemand", bval)))
2742 return hr;
2744 if (SUCCEEDED(hr = TaskSettings_get_RestartInterval(settings, &s)) && s)
2746 FIXME("RestartInterval not handled.\n");
2747 SysFreeString(s);
2749 if (FAILED(hr = ITaskSettings_get_MultipleInstances(settings, &policy)))
2750 return hr;
2751 if (FAILED(hr = write_text_value(stream, L"MultipleInstancesPolicy", string_from_instances_policy(policy))))
2752 return hr;
2754 WRITE_BOOL_OPTION(DisallowStartIfOnBatteries);
2755 WRITE_BOOL_OPTION(StopIfGoingOnBatteries);
2756 WRITE_BOOL_OPTION(AllowHardTerminate);
2757 WRITE_BOOL_OPTION(StartWhenAvailable);
2758 WRITE_BOOL_OPTION(RunOnlyIfNetworkAvailable);
2759 WRITE_BOOL_OPTION(WakeToRun);
2760 WRITE_BOOL_OPTION(Enabled);
2761 WRITE_BOOL_OPTION(Hidden);
2763 if (SUCCEEDED(hr = TaskSettings_get_DeleteExpiredTaskAfter(settings, &s)) && s)
2765 hr = write_text_value(stream, L"DeleteExpiredTaskAfter", s);
2766 SysFreeString(s);
2767 if (FAILED(hr))
2768 return hr;
2770 if (SUCCEEDED(hr = TaskSettings_get_IdleSettings(settings, &idle_settings)))
2772 FIXME("IdleSettings not handled.\n");
2773 IIdleSettings_Release(idle_settings);
2775 if (SUCCEEDED(hr = TaskSettings_get_NetworkSettings(settings, &network_settings)))
2777 FIXME("NetworkSettings not handled.\n");
2778 INetworkSettings_Release(network_settings);
2780 if (SUCCEEDED(hr = TaskSettings_get_ExecutionTimeLimit(settings, &s)) && s)
2782 hr = write_text_value(stream, L"ExecutionTimeLimit", s);
2783 SysFreeString(s);
2784 if (FAILED(hr))
2785 return hr;
2787 if (FAILED(hr = ITaskSettings_get_Priority(settings, &ival)))
2788 return hr;
2789 if (FAILED(hr = write_int_value(stream, L"Priority", ival)))
2790 return hr;
2792 WRITE_BOOL_OPTION(RunOnlyIfIdle);
2793 #undef WRITE_BOOL_OPTION
2795 pop_indent();
2796 write_element_end(stream, L"Settings");
2798 return S_OK;
2801 static HRESULT write_triggers(IStream *stream, ITriggerCollection *triggers)
2803 if (!triggers)
2804 return write_empty_element(stream, L"Triggers");
2806 FIXME("stub\n");
2807 return S_OK;
2810 static HRESULT write_actions(IStream *stream, IActionCollection *actions)
2812 if (!actions)
2814 write_element(stream, L"Actions");
2815 push_indent();
2816 write_empty_element(stream, L"Exec");
2817 pop_indent();
2818 return write_element_end(stream, L"Actions");
2821 FIXME("stub\n");
2822 return S_OK;
2825 static HRESULT WINAPI TaskDefinition_get_XmlText(ITaskDefinition *iface, BSTR *xml)
2827 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2828 HRESULT hr;
2829 IStream *stream;
2830 HGLOBAL hmem;
2831 void *p;
2833 TRACE("%p,%p\n", iface, xml);
2835 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16);
2836 if (!hmem) return E_OUTOFMEMORY;
2838 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2839 if (hr != S_OK)
2841 GlobalFree(hmem);
2842 return hr;
2845 hr = write_task_attributes(stream, &taskdef->ITaskDefinition_iface);
2846 if (hr != S_OK) goto failed;
2848 push_indent();
2850 hr = write_registration_info(stream, taskdef->reginfo);
2851 if (hr != S_OK) goto failed;
2853 hr = write_triggers(stream, taskdef->triggers);
2854 if (hr != S_OK) goto failed;
2856 hr = write_principal(stream, taskdef->principal);
2857 if (hr != S_OK) goto failed;
2859 hr = write_settings(stream, taskdef->taskset);
2860 if (hr != S_OK) goto failed;
2862 hr = write_actions(stream, taskdef->actions);
2863 if (hr != S_OK) goto failed;
2865 pop_indent();
2867 write_element_end(stream, L"Task");
2868 IStream_Write(stream, "\0\0", 2, NULL);
2870 p = GlobalLock(hmem);
2871 *xml = SysAllocString(p);
2872 GlobalUnlock(hmem);
2874 IStream_Release(stream);
2876 return *xml ? S_OK : E_OUTOFMEMORY;
2878 failed:
2879 IStream_Release(stream);
2880 return hr;
2883 static HRESULT read_text_value(IXmlReader *reader, WCHAR **value)
2885 HRESULT hr;
2886 XmlNodeType type;
2888 while (IXmlReader_Read(reader, &type) == S_OK)
2890 switch (type)
2892 case XmlNodeType_Text:
2893 hr = IXmlReader_GetValue(reader, (const WCHAR **)value, NULL);
2894 if (hr != S_OK) return hr;
2895 TRACE("%s\n", debugstr_w(*value));
2896 return S_OK;
2898 case XmlNodeType_Whitespace:
2899 case XmlNodeType_Comment:
2900 break;
2902 default:
2903 FIXME("unexpected node type %d\n", type);
2904 return E_FAIL;
2908 return E_FAIL;
2911 static HRESULT read_variantbool_value(IXmlReader *reader, VARIANT_BOOL *vbool)
2913 HRESULT hr;
2914 WCHAR *value;
2916 hr = read_text_value(reader, &value);
2917 if (hr != S_OK) return hr;
2919 if (!lstrcmpW(value, L"true"))
2920 *vbool = VARIANT_TRUE;
2921 else if (!lstrcmpW(value, L"false"))
2922 *vbool = VARIANT_FALSE;
2923 else
2925 WARN("unexpected bool value %s\n", debugstr_w(value));
2926 return SCHED_E_INVALIDVALUE;
2929 return S_OK;
2932 static HRESULT read_int_value(IXmlReader *reader, int *int_val)
2934 HRESULT hr;
2935 WCHAR *value;
2937 hr = read_text_value(reader, &value);
2938 if (hr != S_OK) return hr;
2940 *int_val = wcstol(value, NULL, 10);
2942 return S_OK;
2945 static HRESULT read_triggers(IXmlReader *reader, ITaskDefinition *taskdef)
2947 FIXME("stub\n");
2948 return S_OK;
2951 static HRESULT read_principal_attributes(IXmlReader *reader, IPrincipal *principal)
2953 HRESULT hr;
2954 const WCHAR *name;
2955 const WCHAR *value;
2957 hr = IXmlReader_MoveToFirstAttribute(reader);
2959 while (hr == S_OK)
2961 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2962 if (hr != S_OK) break;
2964 hr = IXmlReader_GetValue(reader, &value, NULL);
2965 if (hr != S_OK) break;
2967 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
2969 if (!lstrcmpW(name, L"id"))
2970 IPrincipal_put_Id(principal, (BSTR)value);
2971 else
2972 FIXME("unhandled Principal attribute %s\n", debugstr_w(name));
2974 hr = IXmlReader_MoveToNextAttribute(reader);
2977 return S_OK;
2980 static HRESULT read_principal(IXmlReader *reader, IPrincipal *principal)
2982 HRESULT hr;
2983 XmlNodeType type;
2984 const WCHAR *name;
2985 WCHAR *value;
2987 if (IXmlReader_IsEmptyElement(reader))
2989 TRACE("Principal is empty\n");
2990 return S_OK;
2993 read_principal_attributes(reader, principal);
2995 while (IXmlReader_Read(reader, &type) == S_OK)
2997 switch (type)
2999 case XmlNodeType_EndElement:
3000 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3001 if (hr != S_OK) return hr;
3003 TRACE("/%s\n", debugstr_w(name));
3005 if (!lstrcmpW(name, L"Principal"))
3006 return S_OK;
3008 break;
3010 case XmlNodeType_Element:
3011 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3012 if (hr != S_OK) return hr;
3014 TRACE("Element: %s\n", debugstr_w(name));
3016 if (!lstrcmpW(name, L"UserId"))
3018 hr = read_text_value(reader, &value);
3019 if (hr == S_OK)
3020 IPrincipal_put_UserId(principal, value);
3022 else if (!lstrcmpW(name, L"LogonType"))
3024 hr = read_text_value(reader, &value);
3025 if (hr == S_OK)
3027 TASK_LOGON_TYPE logon = TASK_LOGON_NONE;
3029 if (!lstrcmpW(value, L"InteractiveToken"))
3030 logon = TASK_LOGON_INTERACTIVE_TOKEN;
3031 else
3032 FIXME("unhandled LogonType %s\n", debugstr_w(value));
3034 IPrincipal_put_LogonType(principal, logon);
3037 else if (!lstrcmpW(name, L"RunLevel"))
3039 hr = read_text_value(reader, &value);
3040 if (hr == S_OK)
3042 TASK_RUNLEVEL_TYPE level = TASK_RUNLEVEL_LUA;
3044 if (!lstrcmpW(value, L"LeastPrivilege"))
3045 level = TASK_RUNLEVEL_LUA;
3046 else
3047 FIXME("unhandled RunLevel %s\n", debugstr_w(value));
3049 IPrincipal_put_RunLevel(principal, level);
3052 else
3053 FIXME("unhandled Principal element %s\n", debugstr_w(name));
3055 break;
3057 case XmlNodeType_Whitespace:
3058 case XmlNodeType_Comment:
3059 break;
3061 default:
3062 FIXME("unhandled Principal node type %d\n", type);
3063 break;
3067 WARN("Principal was not terminated\n");
3068 return E_FAIL;
3071 static HRESULT read_principals(IXmlReader *reader, ITaskDefinition *taskdef)
3073 HRESULT hr;
3074 XmlNodeType type;
3075 const WCHAR *name;
3077 if (IXmlReader_IsEmptyElement(reader))
3079 TRACE("Principals is empty\n");
3080 return S_OK;
3083 while (IXmlReader_Read(reader, &type) == S_OK)
3085 switch (type)
3087 case XmlNodeType_EndElement:
3088 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3089 if (hr != S_OK) return hr;
3091 TRACE("/%s\n", debugstr_w(name));
3093 if (!lstrcmpW(name, L"Principals"))
3094 return S_OK;
3096 break;
3098 case XmlNodeType_Element:
3099 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3100 if (hr != S_OK) return hr;
3102 TRACE("Element: %s\n", debugstr_w(name));
3104 if (!lstrcmpW(name, L"Principal"))
3106 IPrincipal *principal;
3108 hr = ITaskDefinition_get_Principal(taskdef, &principal);
3109 if (hr != S_OK) return hr;
3110 hr = read_principal(reader, principal);
3111 IPrincipal_Release(principal);
3113 else
3114 FIXME("unhandled Principals element %s\n", debugstr_w(name));
3116 break;
3118 case XmlNodeType_Whitespace:
3119 case XmlNodeType_Comment:
3120 break;
3122 default:
3123 FIXME("unhandled Principals node type %d\n", type);
3124 break;
3128 WARN("Principals was not terminated\n");
3129 return E_FAIL;
3132 static HRESULT read_actions(IXmlReader *reader, ITaskDefinition *taskdef)
3134 FIXME("stub\n");
3135 return S_OK;
3138 static HRESULT read_idle_settings(IXmlReader *reader, ITaskSettings *taskset)
3140 FIXME("stub\n");
3141 return S_OK;
3144 static HRESULT read_settings(IXmlReader *reader, ITaskSettings *taskset)
3146 HRESULT hr;
3147 XmlNodeType type;
3148 const WCHAR *name;
3149 WCHAR *value;
3150 VARIANT_BOOL bool_val;
3151 int int_val;
3153 if (IXmlReader_IsEmptyElement(reader))
3155 TRACE("Settings is empty\n");
3156 return S_OK;
3159 while (IXmlReader_Read(reader, &type) == S_OK)
3161 switch (type)
3163 case XmlNodeType_EndElement:
3164 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3165 if (hr != S_OK) return hr;
3167 TRACE("/%s\n", debugstr_w(name));
3169 if (!lstrcmpW(name, L"Settings"))
3170 return S_OK;
3172 break;
3174 case XmlNodeType_Element:
3175 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3176 if (hr != S_OK) return hr;
3178 TRACE("Element: %s\n", debugstr_w(name));
3180 if (!lstrcmpW(name, L"MultipleInstancesPolicy"))
3182 hr = read_text_value(reader, &value);
3183 if (hr == S_OK)
3185 int_val = TASK_INSTANCES_IGNORE_NEW;
3187 if (!lstrcmpW(value, L"IgnoreNew"))
3188 int_val = TASK_INSTANCES_IGNORE_NEW;
3189 else
3190 FIXME("unhandled MultipleInstancesPolicy %s\n", debugstr_w(value));
3192 ITaskSettings_put_MultipleInstances(taskset, int_val);
3195 else if (!lstrcmpW(name, L"DisallowStartIfOnBatteries"))
3197 hr = read_variantbool_value(reader, &bool_val);
3198 if (hr != S_OK) return hr;
3199 ITaskSettings_put_DisallowStartIfOnBatteries(taskset, bool_val);
3201 else if (!lstrcmpW(name, L"AllowStartOnDemand"))
3203 hr = read_variantbool_value(reader, &bool_val);
3204 if (hr != S_OK) return hr;
3205 ITaskSettings_put_AllowDemandStart(taskset, bool_val);
3207 else if (!lstrcmpW(name, L"StopIfGoingOnBatteries"))
3209 hr = read_variantbool_value(reader, &bool_val);
3210 if (hr != S_OK) return hr;
3211 ITaskSettings_put_StopIfGoingOnBatteries(taskset, bool_val);
3213 else if (!lstrcmpW(name, L"AllowHardTerminate"))
3215 hr = read_variantbool_value(reader, &bool_val);
3216 if (hr != S_OK) return hr;
3217 ITaskSettings_put_AllowHardTerminate(taskset, bool_val);
3219 else if (!lstrcmpW(name, L"StartWhenAvailable"))
3221 hr = read_variantbool_value(reader, &bool_val);
3222 if (hr != S_OK) return hr;
3223 ITaskSettings_put_StartWhenAvailable(taskset, bool_val);
3225 else if (!lstrcmpW(name, L"RunOnlyIfNetworkAvailable"))
3227 hr = read_variantbool_value(reader, &bool_val);
3228 if (hr != S_OK) return hr;
3229 ITaskSettings_put_RunOnlyIfNetworkAvailable(taskset, bool_val);
3231 else if (!lstrcmpW(name, L"Enabled"))
3233 hr = read_variantbool_value(reader, &bool_val);
3234 if (hr != S_OK) return hr;
3235 ITaskSettings_put_Enabled(taskset, bool_val);
3237 else if (!lstrcmpW(name, L"Hidden"))
3239 hr = read_variantbool_value(reader, &bool_val);
3240 if (hr != S_OK) return hr;
3241 ITaskSettings_put_Hidden(taskset, bool_val);
3243 else if (!lstrcmpW(name, L"RunOnlyIfIdle"))
3245 hr = read_variantbool_value(reader, &bool_val);
3246 if (hr != S_OK) return hr;
3247 ITaskSettings_put_RunOnlyIfIdle(taskset, bool_val);
3249 else if (!lstrcmpW(name, L"WakeToRun"))
3251 hr = read_variantbool_value(reader, &bool_val);
3252 if (hr != S_OK) return hr;
3253 ITaskSettings_put_WakeToRun(taskset, bool_val);
3255 else if (!lstrcmpW(name, L"ExecutionTimeLimit"))
3257 hr = read_text_value(reader, &value);
3258 if (hr == S_OK)
3259 ITaskSettings_put_ExecutionTimeLimit(taskset, value);
3261 else if (!lstrcmpW(name, L"Priority"))
3263 hr = read_int_value(reader, &int_val);
3264 if (hr == S_OK)
3265 ITaskSettings_put_Priority(taskset, int_val);
3267 else if (!lstrcmpW(name, L"IdleSettings"))
3269 hr = read_idle_settings(reader, taskset);
3270 if (hr != S_OK) return hr;
3272 else
3273 FIXME("unhandled Settings element %s\n", debugstr_w(name));
3275 break;
3277 case XmlNodeType_Whitespace:
3278 case XmlNodeType_Comment:
3279 break;
3281 default:
3282 FIXME("unhandled Settings node type %d\n", type);
3283 break;
3287 WARN("Settings was not terminated\n");
3288 return SCHED_E_MALFORMEDXML;
3291 static HRESULT read_registration_info(IXmlReader *reader, IRegistrationInfo *info)
3293 HRESULT hr;
3294 XmlNodeType type;
3295 const WCHAR *name;
3296 WCHAR *value;
3298 if (IXmlReader_IsEmptyElement(reader))
3300 TRACE("RegistrationInfo is empty\n");
3301 return S_OK;
3304 while (IXmlReader_Read(reader, &type) == S_OK)
3306 switch (type)
3308 case XmlNodeType_EndElement:
3309 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3310 if (hr != S_OK) return hr;
3312 TRACE("/%s\n", debugstr_w(name));
3314 if (!lstrcmpW(name, L"RegistrationInfo"))
3315 return S_OK;
3317 break;
3319 case XmlNodeType_Element:
3320 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3321 if (hr != S_OK) return hr;
3323 TRACE("Element: %s\n", debugstr_w(name));
3325 if (!lstrcmpW(name, L"Author"))
3327 hr = read_text_value(reader, &value);
3328 if (hr == S_OK)
3329 IRegistrationInfo_put_Author(info, value);
3331 else if (!lstrcmpW(name, L"Description"))
3333 hr = read_text_value(reader, &value);
3334 if (hr == S_OK)
3335 IRegistrationInfo_put_Description(info, value);
3337 else if (!lstrcmpW(name, L"Version"))
3339 hr = read_text_value(reader, &value);
3340 if (hr == S_OK)
3341 IRegistrationInfo_put_Version(info, value);
3343 else if (!lstrcmpW(name, L"Date"))
3345 hr = read_text_value(reader, &value);
3346 if (hr == S_OK)
3347 IRegistrationInfo_put_Date(info, value);
3349 else if (!lstrcmpW(name, L"Documentation"))
3351 hr = read_text_value(reader, &value);
3352 if (hr == S_OK)
3353 IRegistrationInfo_put_Documentation(info, value);
3355 else if (!lstrcmpW(name, L"URI"))
3357 hr = read_text_value(reader, &value);
3358 if (hr == S_OK)
3359 IRegistrationInfo_put_URI(info, value);
3361 else if (!lstrcmpW(name, L"Source"))
3363 hr = read_text_value(reader, &value);
3364 if (hr == S_OK)
3365 IRegistrationInfo_put_Source(info, value);
3367 else
3368 FIXME("unhandled RegistrationInfo element %s\n", debugstr_w(name));
3370 break;
3372 case XmlNodeType_Whitespace:
3373 case XmlNodeType_Comment:
3374 break;
3376 default:
3377 FIXME("unhandled RegistrationInfo node type %d\n", type);
3378 break;
3382 WARN("RegistrationInfo was not terminated\n");
3383 return SCHED_E_MALFORMEDXML;
3386 static HRESULT read_task_attributes(IXmlReader *reader, ITaskDefinition *taskdef)
3388 HRESULT hr;
3389 ITaskSettings *taskset;
3390 const WCHAR *name;
3391 const WCHAR *value;
3392 BOOL xmlns_ok = FALSE;
3394 TRACE("\n");
3396 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3397 if (hr != S_OK) return hr;
3399 hr = IXmlReader_MoveToFirstAttribute(reader);
3401 while (hr == S_OK)
3403 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3404 if (hr != S_OK) break;
3406 hr = IXmlReader_GetValue(reader, &value, NULL);
3407 if (hr != S_OK) break;
3409 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
3411 if (!lstrcmpW(name, L"version"))
3413 TASK_COMPATIBILITY compatibility = TASK_COMPATIBILITY_V2;
3415 if (!lstrcmpW(value, L"1.0"))
3416 compatibility = TASK_COMPATIBILITY_AT;
3417 else if (!lstrcmpW(value, L"1.1"))
3418 compatibility = TASK_COMPATIBILITY_V1;
3419 else if (!lstrcmpW(value, L"1.2"))
3420 compatibility = TASK_COMPATIBILITY_V2;
3421 else if (!lstrcmpW(value, L"1.3"))
3422 compatibility = TASK_COMPATIBILITY_V2_1;
3423 else
3424 FIXME("unknown version %s\n", debugstr_w(value));
3426 ITaskSettings_put_Compatibility(taskset, compatibility);
3428 else if (!lstrcmpW(name, L"xmlns"))
3430 if (lstrcmpW(value, L"http://schemas.microsoft.com/windows/2004/02/mit/task"))
3432 FIXME("unknown namespace %s\n", debugstr_w(value));
3433 break;
3435 xmlns_ok = TRUE;
3437 else
3438 FIXME("unhandled Task attribute %s\n", debugstr_w(name));
3440 hr = IXmlReader_MoveToNextAttribute(reader);
3443 ITaskSettings_Release(taskset);
3444 return xmlns_ok ? S_OK : SCHED_E_NAMESPACE;
3447 static HRESULT read_task(IXmlReader *reader, ITaskDefinition *taskdef)
3449 HRESULT hr;
3450 XmlNodeType type;
3451 const WCHAR *name;
3453 if (IXmlReader_IsEmptyElement(reader))
3455 TRACE("Task is empty\n");
3456 return S_OK;
3459 while (IXmlReader_Read(reader, &type) == S_OK)
3461 switch (type)
3463 case XmlNodeType_EndElement:
3464 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3465 if (hr != S_OK) return hr;
3467 TRACE("/%s\n", debugstr_w(name));
3469 if (!lstrcmpW(name, L"Task"))
3470 return S_OK;
3472 break;
3474 case XmlNodeType_Element:
3475 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3476 if (hr != S_OK) return hr;
3478 TRACE("Element: %s\n", debugstr_w(name));
3480 if (!lstrcmpW(name, L"RegistrationInfo"))
3482 IRegistrationInfo *info;
3484 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &info);
3485 if (hr != S_OK) return hr;
3486 hr = read_registration_info(reader, info);
3487 IRegistrationInfo_Release(info);
3489 else if (!lstrcmpW(name, L"Settings"))
3491 ITaskSettings *taskset;
3493 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3494 if (hr != S_OK) return hr;
3495 hr = read_settings(reader, taskset);
3496 ITaskSettings_Release(taskset);
3498 else if (!lstrcmpW(name, L"Triggers"))
3499 hr = read_triggers(reader, taskdef);
3500 else if (!lstrcmpW(name, L"Principals"))
3501 hr = read_principals(reader, taskdef);
3502 else if (!lstrcmpW(name, L"Actions"))
3503 hr = read_actions(reader, taskdef);
3504 else
3505 FIXME("unhandled Task element %s\n", debugstr_w(name));
3507 if (hr != S_OK) return hr;
3508 break;
3510 case XmlNodeType_Comment:
3511 case XmlNodeType_Whitespace:
3512 break;
3514 default:
3515 FIXME("unhandled Task node type %d\n", type);
3516 break;
3520 WARN("Task was not terminated\n");
3521 return SCHED_E_MALFORMEDXML;
3524 static HRESULT read_xml(IXmlReader *reader, ITaskDefinition *taskdef)
3526 HRESULT hr;
3527 XmlNodeType type;
3528 const WCHAR *name;
3530 while (IXmlReader_Read(reader, &type) == S_OK)
3532 switch (type)
3534 case XmlNodeType_XmlDeclaration:
3535 TRACE("XmlDeclaration\n");
3536 break;
3538 case XmlNodeType_Element:
3539 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3540 if (hr != S_OK) return hr;
3542 TRACE("Element: %s\n", debugstr_w(name));
3544 if (!lstrcmpW(name, L"Task"))
3546 hr = read_task_attributes(reader, taskdef);
3547 if (hr != S_OK) return hr;
3549 return read_task(reader, taskdef);
3551 else
3552 FIXME("unhandled XML element %s\n", debugstr_w(name));
3554 break;
3556 case XmlNodeType_Comment:
3557 case XmlNodeType_Whitespace:
3558 break;
3560 default:
3561 FIXME("unhandled XML node type %d\n", type);
3562 break;
3566 WARN("Task definition was not found\n");
3567 return SCHED_E_MALFORMEDXML;
3570 static HRESULT WINAPI TaskDefinition_put_XmlText(ITaskDefinition *iface, BSTR xml)
3572 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
3573 HRESULT hr;
3574 IStream *stream;
3575 IXmlReader *reader;
3576 HGLOBAL hmem;
3577 void *buf;
3579 TRACE("%p,%s\n", iface, debugstr_w(xml));
3581 if (!xml) return E_INVALIDARG;
3583 hmem = GlobalAlloc(0, lstrlenW(xml) * sizeof(WCHAR));
3584 if (!hmem) return E_OUTOFMEMORY;
3586 buf = GlobalLock(hmem);
3587 memcpy(buf, xml, lstrlenW(xml) * sizeof(WCHAR));
3588 GlobalUnlock(hmem);
3590 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
3591 if (hr != S_OK)
3593 GlobalFree(hmem);
3594 return hr;
3597 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
3598 if (hr != S_OK)
3600 IStream_Release(stream);
3601 return hr;
3604 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
3605 if (hr == S_OK)
3607 if (taskdef->reginfo)
3609 IRegistrationInfo_Release(taskdef->reginfo);
3610 taskdef->reginfo = NULL;
3612 if (taskdef->taskset)
3614 ITaskSettings_Release(taskdef->taskset);
3615 taskdef->taskset = NULL;
3617 if (taskdef->triggers)
3619 ITriggerCollection_Release(taskdef->triggers);
3620 taskdef->triggers = NULL;
3622 if (taskdef->principal)
3624 IPrincipal_Release(taskdef->principal);
3625 taskdef->principal = NULL;
3627 if (taskdef->actions)
3629 IActionCollection_Release(taskdef->actions);
3630 taskdef->actions = NULL;
3633 hr = read_xml(reader, iface);
3636 IXmlReader_Release(reader);
3637 IStream_Release(stream);
3639 return hr;
3642 static const ITaskDefinitionVtbl TaskDefinition_vtbl =
3644 TaskDefinition_QueryInterface,
3645 TaskDefinition_AddRef,
3646 TaskDefinition_Release,
3647 TaskDefinition_GetTypeInfoCount,
3648 TaskDefinition_GetTypeInfo,
3649 TaskDefinition_GetIDsOfNames,
3650 TaskDefinition_Invoke,
3651 TaskDefinition_get_RegistrationInfo,
3652 TaskDefinition_put_RegistrationInfo,
3653 TaskDefinition_get_Triggers,
3654 TaskDefinition_put_Triggers,
3655 TaskDefinition_get_Settings,
3656 TaskDefinition_put_Settings,
3657 TaskDefinition_get_Data,
3658 TaskDefinition_put_Data,
3659 TaskDefinition_get_Principal,
3660 TaskDefinition_put_Principal,
3661 TaskDefinition_get_Actions,
3662 TaskDefinition_put_Actions,
3663 TaskDefinition_get_XmlText,
3664 TaskDefinition_put_XmlText
3667 HRESULT TaskDefinition_create(ITaskDefinition **obj)
3669 TaskDefinition *taskdef;
3671 taskdef = heap_alloc_zero(sizeof(*taskdef));
3672 if (!taskdef) return E_OUTOFMEMORY;
3674 taskdef->ITaskDefinition_iface.lpVtbl = &TaskDefinition_vtbl;
3675 taskdef->ref = 1;
3676 *obj = &taskdef->ITaskDefinition_iface;
3678 TRACE("created %p\n", *obj);
3680 return S_OK;
3683 typedef struct
3685 ITaskService ITaskService_iface;
3686 LONG ref;
3687 BOOL connected;
3688 DWORD version;
3689 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3690 } TaskService;
3692 static inline TaskService *impl_from_ITaskService(ITaskService *iface)
3694 return CONTAINING_RECORD(iface, TaskService, ITaskService_iface);
3697 static ULONG WINAPI TaskService_AddRef(ITaskService *iface)
3699 TaskService *task_svc = impl_from_ITaskService(iface);
3700 return InterlockedIncrement(&task_svc->ref);
3703 static ULONG WINAPI TaskService_Release(ITaskService *iface)
3705 TaskService *task_svc = impl_from_ITaskService(iface);
3706 LONG ref = InterlockedDecrement(&task_svc->ref);
3708 if (!ref)
3710 TRACE("destroying %p\n", iface);
3711 heap_free(task_svc);
3714 return ref;
3717 static HRESULT WINAPI TaskService_QueryInterface(ITaskService *iface, REFIID riid, void **obj)
3719 if (!riid || !obj) return E_INVALIDARG;
3721 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
3723 if (IsEqualGUID(riid, &IID_ITaskService) ||
3724 IsEqualGUID(riid, &IID_IDispatch) ||
3725 IsEqualGUID(riid, &IID_IUnknown))
3727 ITaskService_AddRef(iface);
3728 *obj = iface;
3729 return S_OK;
3732 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
3733 *obj = NULL;
3734 return E_NOINTERFACE;
3737 static HRESULT WINAPI TaskService_GetTypeInfoCount(ITaskService *iface, UINT *count)
3739 FIXME("%p,%p: stub\n", iface, count);
3740 return E_NOTIMPL;
3743 static HRESULT WINAPI TaskService_GetTypeInfo(ITaskService *iface, UINT index, LCID lcid, ITypeInfo **info)
3745 FIXME("%p,%u,%lu,%p: stub\n", iface, index, lcid, info);
3746 return E_NOTIMPL;
3749 static HRESULT WINAPI TaskService_GetIDsOfNames(ITaskService *iface, REFIID riid, LPOLESTR *names,
3750 UINT count, LCID lcid, DISPID *dispid)
3752 FIXME("%p,%s,%p,%u,%lu,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
3753 return E_NOTIMPL;
3756 static HRESULT WINAPI TaskService_Invoke(ITaskService *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
3757 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
3759 FIXME("%p,%ld,%s,%04lx,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
3760 params, result, excepinfo, argerr);
3761 return E_NOTIMPL;
3764 static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITaskFolder **folder)
3766 TaskService *task_svc = impl_from_ITaskService(iface);
3768 TRACE("%p,%s,%p\n", iface, debugstr_w(path), folder);
3770 if (!folder) return E_POINTER;
3772 if (!task_svc->connected)
3773 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3775 return TaskFolder_create(path, NULL, folder, FALSE);
3778 static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks)
3780 FIXME("%p,%lx,%p: stub\n", iface, flags, tasks);
3781 return E_NOTIMPL;
3784 static HRESULT WINAPI TaskService_NewTask(ITaskService *iface, DWORD flags, ITaskDefinition **definition)
3786 TRACE("%p,%lx,%p\n", iface, flags, definition);
3788 if (!definition) return E_POINTER;
3790 if (flags)
3791 FIXME("unsupported flags %lx\n", flags);
3793 return TaskDefinition_create(definition);
3796 static inline BOOL is_variant_null(const VARIANT *var)
3798 return V_VT(var) == VT_EMPTY || V_VT(var) == VT_NULL ||
3799 (V_VT(var) == VT_BSTR && (V_BSTR(var) == NULL || !*V_BSTR(var)));
3802 static HRESULT start_schedsvc(void)
3804 SC_HANDLE scm, service;
3805 SERVICE_STATUS_PROCESS status;
3806 ULONGLONG start_time;
3807 HRESULT hr = SCHED_E_SERVICE_NOT_RUNNING;
3809 TRACE("Trying to start Schedule service\n");
3811 scm = OpenSCManagerW(NULL, NULL, 0);
3812 if (!scm) return SCHED_E_SERVICE_NOT_INSTALLED;
3814 service = OpenServiceW(scm, L"Schedule", SERVICE_START | SERVICE_QUERY_STATUS);
3815 if (service)
3817 if (StartServiceW(service, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
3819 start_time = GetTickCount64();
3822 DWORD dummy;
3824 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(status), &dummy))
3826 WARN("failed to query scheduler status (%lu)\n", GetLastError());
3827 break;
3830 if (status.dwCurrentState == SERVICE_RUNNING)
3832 hr = S_OK;
3833 break;
3836 if (GetTickCount64() - start_time > 30000) break;
3837 Sleep(1000);
3839 } while (status.dwCurrentState == SERVICE_START_PENDING);
3841 if (status.dwCurrentState != SERVICE_RUNNING)
3842 WARN("scheduler failed to start %lu\n", status.dwCurrentState);
3844 else
3845 WARN("failed to start scheduler service (%lu)\n", GetLastError());
3847 CloseServiceHandle(service);
3849 else
3850 WARN("failed to open scheduler service (%lu)\n", GetLastError());
3852 CloseServiceHandle(scm);
3853 return hr;
3856 static HRESULT WINAPI TaskService_Connect(ITaskService *iface, VARIANT server, VARIANT user, VARIANT domain, VARIANT password)
3858 static WCHAR ncalrpc[] = L"ncalrpc";
3859 TaskService *task_svc = impl_from_ITaskService(iface);
3860 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3861 DWORD len;
3862 HRESULT hr;
3863 RPC_WSTR binding_str;
3864 extern handle_t schrpc_handle;
3866 TRACE("%p,%s,%s,%s,%s\n", iface, debugstr_variant(&server), debugstr_variant(&user),
3867 debugstr_variant(&domain), debugstr_variant(&password));
3869 if (!is_variant_null(&user) || !is_variant_null(&domain) || !is_variant_null(&password))
3870 FIXME("user/domain/password are ignored\n");
3872 len = ARRAY_SIZE(comp_name);
3873 if (!GetComputerNameW(comp_name, &len))
3874 return HRESULT_FROM_WIN32(GetLastError());
3876 if (!is_variant_null(&server))
3878 const WCHAR *server_name;
3880 if (V_VT(&server) != VT_BSTR)
3882 FIXME("server variant type %d is not supported\n", V_VT(&server));
3883 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3886 /* skip UNC prefix if any */
3887 server_name = V_BSTR(&server);
3888 if (server_name[0] == '\\' && server_name[1] == '\\')
3889 server_name += 2;
3891 if (wcsicmp(server_name, comp_name))
3893 FIXME("connection to remote server %s is not supported\n", debugstr_w(V_BSTR(&server)));
3894 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3898 hr = start_schedsvc();
3899 if (hr != S_OK) return hr;
3901 hr = RpcStringBindingComposeW(NULL, ncalrpc, NULL, NULL, NULL, &binding_str);
3902 if (hr != RPC_S_OK) return hr;
3903 hr = RpcBindingFromStringBindingW(binding_str, &schrpc_handle);
3904 RpcStringFreeW(&binding_str);
3905 if (hr != RPC_S_OK) return hr;
3907 /* Make sure that the connection works */
3908 hr = SchRpcHighestVersion(&task_svc->version);
3909 if (hr != S_OK) return hr;
3911 TRACE("server version %#lx\n", task_svc->version);
3913 lstrcpyW(task_svc->comp_name, comp_name);
3914 task_svc->connected = TRUE;
3916 return S_OK;
3919 static HRESULT WINAPI TaskService_get_Connected(ITaskService *iface, VARIANT_BOOL *connected)
3921 TaskService *task_svc = impl_from_ITaskService(iface);
3923 TRACE("%p,%p\n", iface, connected);
3925 if (!connected) return E_POINTER;
3927 *connected = task_svc->connected ? VARIANT_TRUE : VARIANT_FALSE;
3929 return S_OK;
3932 static HRESULT WINAPI TaskService_get_TargetServer(ITaskService *iface, BSTR *server)
3934 TaskService *task_svc = impl_from_ITaskService(iface);
3936 TRACE("%p,%p\n", iface, server);
3938 if (!server) return E_POINTER;
3940 if (!task_svc->connected)
3941 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3943 *server = SysAllocString(task_svc->comp_name);
3944 if (!*server) return E_OUTOFMEMORY;
3946 return S_OK;
3949 static HRESULT WINAPI TaskService_get_ConnectedUser(ITaskService *iface, BSTR *user)
3951 FIXME("%p,%p: stub\n", iface, user);
3952 return E_NOTIMPL;
3955 static HRESULT WINAPI TaskService_get_ConnectedDomain(ITaskService *iface, BSTR *domain)
3957 FIXME("%p,%p: stub\n", iface, domain);
3958 return E_NOTIMPL;
3961 static HRESULT WINAPI TaskService_get_HighestVersion(ITaskService *iface, DWORD *version)
3963 TaskService *task_svc = impl_from_ITaskService(iface);
3965 TRACE("%p,%p\n", iface, version);
3967 if (!version) return E_POINTER;
3969 if (!task_svc->connected)
3970 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3972 *version = task_svc->version;
3974 return S_OK;
3977 static const ITaskServiceVtbl TaskService_vtbl =
3979 TaskService_QueryInterface,
3980 TaskService_AddRef,
3981 TaskService_Release,
3982 TaskService_GetTypeInfoCount,
3983 TaskService_GetTypeInfo,
3984 TaskService_GetIDsOfNames,
3985 TaskService_Invoke,
3986 TaskService_GetFolder,
3987 TaskService_GetRunningTasks,
3988 TaskService_NewTask,
3989 TaskService_Connect,
3990 TaskService_get_Connected,
3991 TaskService_get_TargetServer,
3992 TaskService_get_ConnectedUser,
3993 TaskService_get_ConnectedDomain,
3994 TaskService_get_HighestVersion
3997 HRESULT TaskService_create(void **obj)
3999 TaskService *task_svc;
4001 task_svc = heap_alloc(sizeof(*task_svc));
4002 if (!task_svc) return E_OUTOFMEMORY;
4004 task_svc->ITaskService_iface.lpVtbl = &TaskService_vtbl;
4005 task_svc->ref = 1;
4006 task_svc->connected = FALSE;
4007 *obj = &task_svc->ITaskService_iface;
4009 TRACE("created %p\n", *obj);
4011 return S_OK;
4014 void __RPC_FAR *__RPC_USER MIDL_user_allocate(SIZE_T n)
4016 return HeapAlloc(GetProcessHeap(), 0, n);
4019 void __RPC_USER MIDL_user_free(void __RPC_FAR *p)
4021 HeapFree(GetProcessHeap(), 0, p);