taskschd: Implement IExecAction_get_Path.
[wine.git] / dlls / taskschd / task.c
blobdf75236d9dc41c19f7ad4769c15496729ba40dc8
1 /*
2 * Copyright 2013 Dmitry Timoshkov
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "initguid.h"
26 #include "objbase.h"
27 #include "xmllite.h"
28 #include "taskschd.h"
29 #include "winsvc.h"
30 #include "schrpc.h"
31 #include "taskschd_private.h"
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(taskschd);
38 typedef struct {
39 IDailyTrigger IDailyTrigger_iface;
40 LONG ref;
41 short interval;
42 } DailyTrigger;
44 static inline DailyTrigger *impl_from_IDailyTrigger(IDailyTrigger *iface)
46 return CONTAINING_RECORD(iface, DailyTrigger, IDailyTrigger_iface);
49 static HRESULT WINAPI DailyTrigger_QueryInterface(IDailyTrigger *iface, REFIID riid, void **ppv)
51 DailyTrigger *This = impl_from_IDailyTrigger(iface);
53 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
55 if(IsEqualGUID(&IID_IUnknown, riid) ||
56 IsEqualGUID(&IID_IDispatch, riid) ||
57 IsEqualGUID(&IID_ITrigger, riid) ||
58 IsEqualGUID(&IID_IDailyTrigger, riid))
60 *ppv = &This->IDailyTrigger_iface;
62 else
64 FIXME("unsupported riid %s\n", debugstr_guid(riid));
65 *ppv = NULL;
66 return E_NOINTERFACE;
69 IUnknown_AddRef((IUnknown*)*ppv);
70 return S_OK;
73 static ULONG WINAPI DailyTrigger_AddRef(IDailyTrigger *iface)
75 DailyTrigger *This = impl_from_IDailyTrigger(iface);
76 LONG ref = InterlockedIncrement(&This->ref);
78 TRACE("(%p) ref=%d\n", This, ref);
80 return ref;
83 static ULONG WINAPI DailyTrigger_Release(IDailyTrigger *iface)
85 DailyTrigger *This = impl_from_IDailyTrigger(iface);
86 LONG ref = InterlockedDecrement(&This->ref);
88 TRACE("(%p) ref=%d\n", This, ref);
90 if(!ref)
91 heap_free(This);
93 return ref;
96 static HRESULT WINAPI DailyTrigger_GetTypeInfoCount(IDailyTrigger *iface, UINT *count)
98 DailyTrigger *This = impl_from_IDailyTrigger(iface);
99 FIXME("(%p)->(%p)\n", This, count);
100 return E_NOTIMPL;
103 static HRESULT WINAPI DailyTrigger_GetTypeInfo(IDailyTrigger *iface, UINT index, LCID lcid, ITypeInfo **info)
105 DailyTrigger *This = impl_from_IDailyTrigger(iface);
106 FIXME("(%p)->(%u %u %p)\n", This, index, lcid, info);
107 return E_NOTIMPL;
110 static HRESULT WINAPI DailyTrigger_GetIDsOfNames(IDailyTrigger *iface, REFIID riid, LPOLESTR *names,
111 UINT count, LCID lcid, DISPID *dispid)
113 DailyTrigger *This = impl_from_IDailyTrigger(iface);
114 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), names, count, lcid, dispid);
115 return E_NOTIMPL;
118 static HRESULT WINAPI DailyTrigger_Invoke(IDailyTrigger *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
119 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
121 DailyTrigger *This = impl_from_IDailyTrigger(iface);
122 FIXME("(%p)->(%d %s %x %x %p %p %p %p)\n", This, dispid, debugstr_guid(riid), lcid, flags,
123 params, result, excepinfo, argerr);
124 return E_NOTIMPL;
127 static HRESULT WINAPI DailyTrigger_get_Type(IDailyTrigger *iface, TASK_TRIGGER_TYPE2 *type)
129 DailyTrigger *This = impl_from_IDailyTrigger(iface);
130 FIXME("(%p)->(%p)\n", This, type);
131 return E_NOTIMPL;
134 static HRESULT WINAPI DailyTrigger_get_Id(IDailyTrigger *iface, BSTR *id)
136 DailyTrigger *This = impl_from_IDailyTrigger(iface);
137 FIXME("(%p)->(%p)\n", This, id);
138 return E_NOTIMPL;
141 static HRESULT WINAPI DailyTrigger_put_Id(IDailyTrigger *iface, BSTR id)
143 DailyTrigger *This = impl_from_IDailyTrigger(iface);
144 FIXME("(%p)->(%s)\n", This, debugstr_w(id));
145 return E_NOTIMPL;
148 static HRESULT WINAPI DailyTrigger_get_Repetition(IDailyTrigger *iface, IRepetitionPattern **repeat)
150 DailyTrigger *This = impl_from_IDailyTrigger(iface);
151 FIXME("(%p)->(%p)\n", This, repeat);
152 return E_NOTIMPL;
155 static HRESULT WINAPI DailyTrigger_put_Repetition(IDailyTrigger *iface, IRepetitionPattern *repeat)
157 DailyTrigger *This = impl_from_IDailyTrigger(iface);
158 FIXME("(%p)->(%p)\n", This, repeat);
159 return E_NOTIMPL;
162 static HRESULT WINAPI DailyTrigger_get_ExecutionTimeLimit(IDailyTrigger *iface, BSTR *limit)
164 DailyTrigger *This = impl_from_IDailyTrigger(iface);
165 FIXME("(%p)->(%p)\n", This, limit);
166 return E_NOTIMPL;
169 static HRESULT WINAPI DailyTrigger_put_ExecutionTimeLimit(IDailyTrigger *iface, BSTR limit)
171 DailyTrigger *This = impl_from_IDailyTrigger(iface);
172 FIXME("(%p)->(%s)\n", This, debugstr_w(limit));
173 return E_NOTIMPL;
176 static HRESULT WINAPI DailyTrigger_get_StartBoundary(IDailyTrigger *iface, BSTR *start)
178 DailyTrigger *This = impl_from_IDailyTrigger(iface);
179 FIXME("(%p)->(%p)\n", This, start);
180 return E_NOTIMPL;
183 static HRESULT WINAPI DailyTrigger_put_StartBoundary(IDailyTrigger *iface, BSTR start)
185 DailyTrigger *This = impl_from_IDailyTrigger(iface);
186 FIXME("(%p)->(%s)\n", This, debugstr_w(start));
187 return S_OK;
190 static HRESULT WINAPI DailyTrigger_get_EndBoundary(IDailyTrigger *iface, BSTR *end)
192 DailyTrigger *This = impl_from_IDailyTrigger(iface);
193 FIXME("(%p)->(%p)\n", This, end);
194 return E_NOTIMPL;
197 static HRESULT WINAPI DailyTrigger_put_EndBoundary(IDailyTrigger *iface, BSTR end)
199 DailyTrigger *This = impl_from_IDailyTrigger(iface);
200 FIXME("(%p)->(%s)\n", This, debugstr_w(end));
201 return E_NOTIMPL;
204 static HRESULT WINAPI DailyTrigger_get_Enabled(IDailyTrigger *iface, VARIANT_BOOL *enabled)
206 DailyTrigger *This = impl_from_IDailyTrigger(iface);
207 FIXME("(%p)->(%p)\n", This, enabled);
208 return E_NOTIMPL;
211 static HRESULT WINAPI DailyTrigger_put_Enabled(IDailyTrigger *iface, VARIANT_BOOL enabled)
213 DailyTrigger *This = impl_from_IDailyTrigger(iface);
214 FIXME("(%p)->(%x)\n", This, enabled);
215 return S_OK;
218 static HRESULT WINAPI DailyTrigger_get_DaysInterval(IDailyTrigger *iface, short *days)
220 DailyTrigger *This = impl_from_IDailyTrigger(iface);
222 TRACE("(%p)->(%p)\n", This, days);
224 *days = This->interval;
225 return S_OK;
228 static HRESULT WINAPI DailyTrigger_put_DaysInterval(IDailyTrigger *iface, short days)
230 DailyTrigger *This = impl_from_IDailyTrigger(iface);
232 TRACE("(%p)->(%d)\n", This, days);
234 if(days <= 0)
235 return E_INVALIDARG;
237 This->interval = days;
238 return S_OK;
241 static HRESULT WINAPI DailyTrigger_get_RandomDelay(IDailyTrigger *iface, BSTR *pRandomDelay)
243 DailyTrigger *This = impl_from_IDailyTrigger(iface);
244 FIXME("(%p)->(%p)\n", This, pRandomDelay);
245 return E_NOTIMPL;
248 static HRESULT WINAPI DailyTrigger_put_RandomDelay(IDailyTrigger *iface, BSTR randomDelay)
250 DailyTrigger *This = impl_from_IDailyTrigger(iface);
251 FIXME("(%p)->(%s)\n", This, debugstr_w(randomDelay));
252 return E_NOTIMPL;
255 static const IDailyTriggerVtbl DailyTrigger_vtbl = {
256 DailyTrigger_QueryInterface,
257 DailyTrigger_AddRef,
258 DailyTrigger_Release,
259 DailyTrigger_GetTypeInfoCount,
260 DailyTrigger_GetTypeInfo,
261 DailyTrigger_GetIDsOfNames,
262 DailyTrigger_Invoke,
263 DailyTrigger_get_Type,
264 DailyTrigger_get_Id,
265 DailyTrigger_put_Id,
266 DailyTrigger_get_Repetition,
267 DailyTrigger_put_Repetition,
268 DailyTrigger_get_ExecutionTimeLimit,
269 DailyTrigger_put_ExecutionTimeLimit,
270 DailyTrigger_get_StartBoundary,
271 DailyTrigger_put_StartBoundary,
272 DailyTrigger_get_EndBoundary,
273 DailyTrigger_put_EndBoundary,
274 DailyTrigger_get_Enabled,
275 DailyTrigger_put_Enabled,
276 DailyTrigger_get_DaysInterval,
277 DailyTrigger_put_DaysInterval,
278 DailyTrigger_get_RandomDelay,
279 DailyTrigger_put_RandomDelay
282 static HRESULT DailyTrigger_create(ITrigger **trigger)
284 DailyTrigger *daily_trigger;
286 daily_trigger = heap_alloc(sizeof(*daily_trigger));
287 if (!daily_trigger)
288 return E_OUTOFMEMORY;
290 daily_trigger->IDailyTrigger_iface.lpVtbl = &DailyTrigger_vtbl;
291 daily_trigger->ref = 1;
292 daily_trigger->interval = 1;
294 *trigger = (ITrigger*)&daily_trigger->IDailyTrigger_iface;
295 return S_OK;
298 typedef struct
300 ITriggerCollection ITriggerCollection_iface;
301 LONG ref;
302 } trigger_collection;
304 static inline trigger_collection *impl_from_ITriggerCollection(ITriggerCollection *iface)
306 return CONTAINING_RECORD(iface, trigger_collection, ITriggerCollection_iface);
309 static HRESULT WINAPI TriggerCollection_QueryInterface(ITriggerCollection *iface, REFIID riid, void **ppv)
311 trigger_collection *This = impl_from_ITriggerCollection(iface);
313 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
315 if(IsEqualGUID(&IID_IUnknown, riid) ||
316 IsEqualGUID(&IID_IDispatch, riid) ||
317 IsEqualGUID(&IID_ITriggerCollection, riid)) {
318 *ppv = &This->ITriggerCollection_iface;
319 }else {
320 FIXME("unimplemented interface %s\n", debugstr_guid(riid));
321 *ppv = NULL;
322 return E_NOINTERFACE;
325 IUnknown_AddRef((IUnknown*)*ppv);
326 return S_OK;
329 static ULONG WINAPI TriggerCollection_AddRef(ITriggerCollection *iface)
331 trigger_collection *This = impl_from_ITriggerCollection(iface);
332 LONG ref = InterlockedIncrement(&This->ref);
334 TRACE("(%p) ref=%d\n", This, ref);
336 return ref;
339 static ULONG WINAPI TriggerCollection_Release(ITriggerCollection *iface)
341 trigger_collection *This = impl_from_ITriggerCollection(iface);
342 LONG ref = InterlockedDecrement(&This->ref);
344 TRACE("(%p) ref=%d\n", This, ref);
346 if(!ref)
347 heap_free(This);
349 return ref;
352 static HRESULT WINAPI TriggerCollection_GetTypeInfoCount(ITriggerCollection *iface, UINT *count)
354 trigger_collection *This = impl_from_ITriggerCollection(iface);
355 FIXME("(%p)->(%p)\n", This, count);
356 return E_NOTIMPL;
359 static HRESULT WINAPI TriggerCollection_GetTypeInfo(ITriggerCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
361 trigger_collection *This = impl_from_ITriggerCollection(iface);
362 FIXME("(%p)->(%u %u %p)\n", This, index, lcid, info);
363 return E_NOTIMPL;
366 static HRESULT WINAPI TriggerCollection_GetIDsOfNames(ITriggerCollection *iface, REFIID riid, LPOLESTR *names,
367 UINT count, LCID lcid, DISPID *dispid)
369 trigger_collection *This = impl_from_ITriggerCollection(iface);
370 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), names, count, lcid, dispid);
371 return E_NOTIMPL;
374 static HRESULT WINAPI TriggerCollection_Invoke(ITriggerCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
375 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
377 trigger_collection *This = impl_from_ITriggerCollection(iface);
378 FIXME("(%p)->(%d %s %x %x %p %p %p %p)\n", This, dispid, debugstr_guid(riid), lcid, flags,
379 params, result, excepinfo, argerr);
380 return E_NOTIMPL;
383 static HRESULT WINAPI TriggerCollection_get_Count(ITriggerCollection *iface, LONG *count)
385 trigger_collection *This = impl_from_ITriggerCollection(iface);
386 FIXME("(%p)->(%p)\n", This, count);
387 return E_NOTIMPL;
390 static HRESULT WINAPI TriggerCollection_get_Item(ITriggerCollection *iface, LONG index, ITrigger **trigger)
392 trigger_collection *This = impl_from_ITriggerCollection(iface);
393 FIXME("(%p)->(%d %p)\n", This, index, trigger);
394 return E_NOTIMPL;
397 static HRESULT WINAPI TriggerCollection_get__NewEnum(ITriggerCollection *iface, IUnknown **penum)
399 trigger_collection *This = impl_from_ITriggerCollection(iface);
400 FIXME("(%p)->(%p)\n", This, penum);
401 return E_NOTIMPL;
404 static HRESULT WINAPI TriggerCollection_Create(ITriggerCollection *iface, TASK_TRIGGER_TYPE2 type, ITrigger **trigger)
406 trigger_collection *This = impl_from_ITriggerCollection(iface);
408 TRACE("(%p)->(%d %p)\n", This, type, trigger);
410 switch(type) {
411 case TASK_TRIGGER_DAILY:
412 return DailyTrigger_create(trigger);
413 default:
414 FIXME("Unimplemented type %d\n", type);
415 return E_NOTIMPL;
418 return S_OK;
421 static HRESULT WINAPI TriggerCollection_Remove(ITriggerCollection *iface, VARIANT index)
423 trigger_collection *This = impl_from_ITriggerCollection(iface);
424 FIXME("(%p)->(%s)\n", This, debugstr_variant(&index));
425 return E_NOTIMPL;
428 static HRESULT WINAPI TriggerCollection_Clear(ITriggerCollection *iface)
430 trigger_collection *This = impl_from_ITriggerCollection(iface);
431 FIXME("(%p)\n", This);
432 return E_NOTIMPL;
435 static const ITriggerCollectionVtbl TriggerCollection_vtbl = {
436 TriggerCollection_QueryInterface,
437 TriggerCollection_AddRef,
438 TriggerCollection_Release,
439 TriggerCollection_GetTypeInfoCount,
440 TriggerCollection_GetTypeInfo,
441 TriggerCollection_GetIDsOfNames,
442 TriggerCollection_Invoke,
443 TriggerCollection_get_Count,
444 TriggerCollection_get_Item,
445 TriggerCollection_get__NewEnum,
446 TriggerCollection_Create,
447 TriggerCollection_Remove,
448 TriggerCollection_Clear
451 typedef struct
453 IRegistrationInfo IRegistrationInfo_iface;
454 LONG ref;
455 WCHAR *description, *author, *version, *date, *documentation, *uri, *source;
456 } registration_info;
458 static inline registration_info *impl_from_IRegistrationInfo(IRegistrationInfo *iface)
460 return CONTAINING_RECORD(iface, registration_info, IRegistrationInfo_iface);
463 static ULONG WINAPI RegistrationInfo_AddRef(IRegistrationInfo *iface)
465 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
466 return InterlockedIncrement(&reginfo->ref);
469 static ULONG WINAPI RegistrationInfo_Release(IRegistrationInfo *iface)
471 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
472 LONG ref = InterlockedDecrement(&reginfo->ref);
474 if (!ref)
476 TRACE("destroying %p\n", iface);
477 heap_free(reginfo->description);
478 heap_free(reginfo->author);
479 heap_free(reginfo->version);
480 heap_free(reginfo->date);
481 heap_free(reginfo->documentation);
482 heap_free(reginfo->uri);
483 heap_free(reginfo->source);
484 heap_free(reginfo);
487 return ref;
490 static HRESULT WINAPI RegistrationInfo_QueryInterface(IRegistrationInfo *iface, REFIID riid, void **obj)
492 if (!riid || !obj) return E_INVALIDARG;
494 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
496 if (IsEqualGUID(riid, &IID_IRegistrationInfo) ||
497 IsEqualGUID(riid, &IID_IDispatch) ||
498 IsEqualGUID(riid, &IID_IUnknown))
500 IRegistrationInfo_AddRef(iface);
501 *obj = iface;
502 return S_OK;
505 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
506 *obj = NULL;
507 return E_NOINTERFACE;
510 static HRESULT WINAPI RegistrationInfo_GetTypeInfoCount(IRegistrationInfo *iface, UINT *count)
512 FIXME("%p,%p: stub\n", iface, count);
513 return E_NOTIMPL;
516 static HRESULT WINAPI RegistrationInfo_GetTypeInfo(IRegistrationInfo *iface, UINT index, LCID lcid, ITypeInfo **info)
518 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
519 return E_NOTIMPL;
522 static HRESULT WINAPI RegistrationInfo_GetIDsOfNames(IRegistrationInfo *iface, REFIID riid, LPOLESTR *names,
523 UINT count, LCID lcid, DISPID *dispid)
525 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
526 return E_NOTIMPL;
529 static HRESULT WINAPI RegistrationInfo_Invoke(IRegistrationInfo *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
530 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
532 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
533 params, result, excepinfo, argerr);
534 return E_NOTIMPL;
537 static HRESULT WINAPI RegistrationInfo_get_Description(IRegistrationInfo *iface, BSTR *description)
539 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
541 TRACE("%p,%p\n", iface, description);
543 if (!description) return E_POINTER;
545 *description = SysAllocString(reginfo->description);
546 return S_OK;
549 static HRESULT WINAPI RegistrationInfo_put_Description(IRegistrationInfo *iface, BSTR description)
551 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
553 TRACE("%p,%s\n", iface, debugstr_w(description));
555 if (!description) return E_INVALIDARG;
557 heap_free(reginfo->description);
558 reginfo->description = heap_strdupW(description);
559 /* FIXME: update XML on the server side */
560 return reginfo->description ? S_OK : E_OUTOFMEMORY;
563 static HRESULT WINAPI RegistrationInfo_get_Author(IRegistrationInfo *iface, BSTR *author)
565 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
567 TRACE("%p,%p\n", iface, author);
569 if (!author) return E_POINTER;
571 *author = SysAllocString(reginfo->author);
572 return S_OK;
575 static HRESULT WINAPI RegistrationInfo_put_Author(IRegistrationInfo *iface, BSTR author)
577 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
579 TRACE("%p,%s\n", iface, debugstr_w(author));
581 if (!author) return E_INVALIDARG;
583 heap_free(reginfo->author);
584 reginfo->author = heap_strdupW(author);
585 /* FIXME: update XML on the server side */
586 return reginfo->author ? S_OK : E_OUTOFMEMORY;
589 static HRESULT WINAPI RegistrationInfo_get_Version(IRegistrationInfo *iface, BSTR *version)
591 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
593 TRACE("%p,%p\n", iface, version);
595 if (!version) return E_POINTER;
597 *version = SysAllocString(reginfo->version);
598 return S_OK;
601 static HRESULT WINAPI RegistrationInfo_put_Version(IRegistrationInfo *iface, BSTR version)
603 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
605 TRACE("%p,%s\n", iface, debugstr_w(version));
607 if (!version) return E_INVALIDARG;
609 heap_free(reginfo->version);
610 reginfo->version = heap_strdupW(version);
611 /* FIXME: update XML on the server side */
612 return reginfo->version ? S_OK : E_OUTOFMEMORY;
615 static HRESULT WINAPI RegistrationInfo_get_Date(IRegistrationInfo *iface, BSTR *date)
617 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
619 TRACE("%p,%p\n", iface, date);
621 if (!date) return E_POINTER;
623 *date = SysAllocString(reginfo->date);
624 return S_OK;
627 static HRESULT WINAPI RegistrationInfo_put_Date(IRegistrationInfo *iface, BSTR date)
629 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
631 TRACE("%p,%s\n", iface, debugstr_w(date));
633 if (!date) return E_INVALIDARG;
635 heap_free(reginfo->date);
636 reginfo->date = heap_strdupW(date);
637 /* FIXME: update XML on the server side */
638 return reginfo->date ? S_OK : E_OUTOFMEMORY;
641 static HRESULT WINAPI RegistrationInfo_get_Documentation(IRegistrationInfo *iface, BSTR *doc)
643 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
645 TRACE("%p,%p\n", iface, doc);
647 if (!doc) return E_POINTER;
649 *doc = SysAllocString(reginfo->documentation);
650 return S_OK;
653 static HRESULT WINAPI RegistrationInfo_put_Documentation(IRegistrationInfo *iface, BSTR doc)
655 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
657 TRACE("%p,%s\n", iface, debugstr_w(doc));
659 if (!doc) return E_INVALIDARG;
661 heap_free(reginfo->documentation);
662 reginfo->documentation = heap_strdupW(doc);
663 /* FIXME: update XML on the server side */
664 return reginfo->documentation ? S_OK : E_OUTOFMEMORY;
667 static HRESULT WINAPI RegistrationInfo_get_XmlText(IRegistrationInfo *iface, BSTR *xml)
669 FIXME("%p,%p: stub\n", iface, xml);
670 return E_NOTIMPL;
673 static HRESULT WINAPI RegistrationInfo_put_XmlText(IRegistrationInfo *iface, BSTR xml)
675 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
676 return E_NOTIMPL;
679 static HRESULT WINAPI RegistrationInfo_get_URI(IRegistrationInfo *iface, BSTR *uri)
681 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
683 TRACE("%p,%p\n", iface, uri);
685 if (!uri) return E_POINTER;
687 *uri = SysAllocString(reginfo->uri);
688 return S_OK;
691 static HRESULT WINAPI RegistrationInfo_put_URI(IRegistrationInfo *iface, BSTR uri)
693 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
695 TRACE("%p,%s\n", iface, debugstr_w(uri));
697 if (!uri) return E_INVALIDARG;
699 heap_free(reginfo->uri);
700 reginfo->uri = heap_strdupW(uri);
701 /* FIXME: update XML on the server side */
702 return reginfo->uri ? S_OK : E_OUTOFMEMORY;
705 static HRESULT WINAPI RegistrationInfo_get_SecurityDescriptor(IRegistrationInfo *iface, VARIANT *sddl)
707 FIXME("%p,%p: stub\n", iface, sddl);
708 return E_NOTIMPL;
711 static HRESULT WINAPI RegistrationInfo_put_SecurityDescriptor(IRegistrationInfo *iface, VARIANT sddl)
713 FIXME("%p,%s: stub\n", iface, debugstr_variant(&sddl));
714 return S_OK;
717 static HRESULT WINAPI RegistrationInfo_get_Source(IRegistrationInfo *iface, BSTR *source)
719 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
721 TRACE("%p,%p\n", iface, source);
723 if (!source) return E_POINTER;
725 *source = SysAllocString(reginfo->source);
726 return S_OK;
729 static HRESULT WINAPI RegistrationInfo_put_Source(IRegistrationInfo *iface, BSTR source)
731 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
733 TRACE("%p,%s\n", iface, debugstr_w(source));
735 if (!source) return E_INVALIDARG;
737 heap_free(reginfo->source);
738 reginfo->source = heap_strdupW(source);
739 /* FIXME: update XML on the server side */
740 return reginfo->source ? S_OK : E_OUTOFMEMORY;
743 static const IRegistrationInfoVtbl RegistrationInfo_vtbl =
745 RegistrationInfo_QueryInterface,
746 RegistrationInfo_AddRef,
747 RegistrationInfo_Release,
748 RegistrationInfo_GetTypeInfoCount,
749 RegistrationInfo_GetTypeInfo,
750 RegistrationInfo_GetIDsOfNames,
751 RegistrationInfo_Invoke,
752 RegistrationInfo_get_Description,
753 RegistrationInfo_put_Description,
754 RegistrationInfo_get_Author,
755 RegistrationInfo_put_Author,
756 RegistrationInfo_get_Version,
757 RegistrationInfo_put_Version,
758 RegistrationInfo_get_Date,
759 RegistrationInfo_put_Date,
760 RegistrationInfo_get_Documentation,
761 RegistrationInfo_put_Documentation,
762 RegistrationInfo_get_XmlText,
763 RegistrationInfo_put_XmlText,
764 RegistrationInfo_get_URI,
765 RegistrationInfo_put_URI,
766 RegistrationInfo_get_SecurityDescriptor,
767 RegistrationInfo_put_SecurityDescriptor,
768 RegistrationInfo_get_Source,
769 RegistrationInfo_put_Source
772 static HRESULT RegistrationInfo_create(IRegistrationInfo **obj)
774 registration_info *reginfo;
776 reginfo = heap_alloc_zero(sizeof(*reginfo));
777 if (!reginfo) return E_OUTOFMEMORY;
779 reginfo->IRegistrationInfo_iface.lpVtbl = &RegistrationInfo_vtbl;
780 reginfo->ref = 1;
781 *obj = &reginfo->IRegistrationInfo_iface;
783 TRACE("created %p\n", *obj);
785 return S_OK;
788 typedef struct
790 ITaskSettings ITaskSettings_iface;
791 LONG ref;
792 WCHAR *restart_interval;
793 WCHAR *execution_time_limit;
794 WCHAR *delete_expired_task_after;
795 int restart_count;
796 int priority;
797 TASK_INSTANCES_POLICY policy;
798 TASK_COMPATIBILITY compatibility;
799 BOOL allow_on_demand_start;
800 BOOL stop_if_going_on_batteries;
801 BOOL disallow_start_if_on_batteries;
802 BOOL allow_hard_terminate;
803 BOOL start_when_available;
804 BOOL run_only_if_network_available;
805 BOOL enabled;
806 BOOL hidden;
807 BOOL run_only_if_idle;
808 BOOL wake_to_run;
809 } TaskSettings;
811 static inline TaskSettings *impl_from_ITaskSettings(ITaskSettings *iface)
813 return CONTAINING_RECORD(iface, TaskSettings, ITaskSettings_iface);
816 static ULONG WINAPI TaskSettings_AddRef(ITaskSettings *iface)
818 TaskSettings *taskset = impl_from_ITaskSettings(iface);
819 return InterlockedIncrement(&taskset->ref);
822 static ULONG WINAPI TaskSettings_Release(ITaskSettings *iface)
824 TaskSettings *taskset = impl_from_ITaskSettings(iface);
825 LONG ref = InterlockedDecrement(&taskset->ref);
827 if (!ref)
829 TRACE("destroying %p\n", iface);
830 heap_free(taskset->restart_interval);
831 heap_free(taskset->execution_time_limit);
832 heap_free(taskset->delete_expired_task_after);
833 heap_free(taskset);
836 return ref;
839 static HRESULT WINAPI TaskSettings_QueryInterface(ITaskSettings *iface, REFIID riid, void **obj)
841 if (!riid || !obj) return E_INVALIDARG;
843 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
845 if (IsEqualGUID(riid, &IID_ITaskSettings) ||
846 IsEqualGUID(riid, &IID_IDispatch) ||
847 IsEqualGUID(riid, &IID_IUnknown))
849 ITaskSettings_AddRef(iface);
850 *obj = iface;
851 return S_OK;
854 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
855 *obj = NULL;
856 return E_NOINTERFACE;
859 static HRESULT WINAPI TaskSettings_GetTypeInfoCount(ITaskSettings *iface, UINT *count)
861 FIXME("%p,%p: stub\n", iface, count);
862 return E_NOTIMPL;
865 static HRESULT WINAPI TaskSettings_GetTypeInfo(ITaskSettings *iface, UINT index, LCID lcid, ITypeInfo **info)
867 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
868 return E_NOTIMPL;
871 static HRESULT WINAPI TaskSettings_GetIDsOfNames(ITaskSettings *iface, REFIID riid, LPOLESTR *names,
872 UINT count, LCID lcid, DISPID *dispid)
874 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
875 return E_NOTIMPL;
878 static HRESULT WINAPI TaskSettings_Invoke(ITaskSettings *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
879 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
881 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
882 params, result, excepinfo, argerr);
883 return E_NOTIMPL;
886 static HRESULT WINAPI TaskSettings_get_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL *allow)
888 TaskSettings *taskset = impl_from_ITaskSettings(iface);
890 TRACE("%p,%p\n", iface, allow);
892 if (!allow) return E_POINTER;
894 *allow = taskset->allow_on_demand_start ? VARIANT_TRUE : VARIANT_FALSE;
896 return S_OK;
899 static HRESULT WINAPI TaskSettings_put_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL allow)
901 TaskSettings *taskset = impl_from_ITaskSettings(iface);
903 TRACE("%p,%d\n", iface, allow);
905 taskset->allow_on_demand_start = allow ? TRUE : FALSE;
907 return S_OK;
910 static HRESULT WINAPI TaskSettings_get_RestartInterval(ITaskSettings *iface, BSTR *interval)
912 TaskSettings *taskset = impl_from_ITaskSettings(iface);
914 TRACE("%p,%p\n", iface, interval);
916 if (!interval) return E_POINTER;
918 if (!taskset->restart_interval)
920 *interval = NULL;
921 return S_OK;
924 *interval = SysAllocString(taskset->restart_interval);
925 if (!*interval) return E_OUTOFMEMORY;
927 return S_OK;
930 static HRESULT WINAPI TaskSettings_put_RestartInterval(ITaskSettings *iface, BSTR interval)
932 TaskSettings *taskset = impl_from_ITaskSettings(iface);
933 WCHAR *str = NULL;
935 TRACE("%p,%s\n", iface, debugstr_w(interval));
937 if (interval && !(str = heap_strdupW(interval))) return E_OUTOFMEMORY;
938 heap_free(taskset->restart_interval);
939 taskset->restart_interval = str;
941 return S_OK;
944 static HRESULT WINAPI TaskSettings_get_RestartCount(ITaskSettings *iface, INT *count)
946 TaskSettings *taskset = impl_from_ITaskSettings(iface);
948 TRACE("%p,%p\n", iface, count);
950 if (!count) return E_POINTER;
952 *count = taskset->restart_count;
954 return S_OK;
957 static HRESULT WINAPI TaskSettings_put_RestartCount(ITaskSettings *iface, INT count)
959 TaskSettings *taskset = impl_from_ITaskSettings(iface);
961 TRACE("%p,%d\n", iface, count);
963 taskset->restart_count = count;
965 return S_OK;
968 static HRESULT WINAPI TaskSettings_get_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY *policy)
970 TaskSettings *taskset = impl_from_ITaskSettings(iface);
972 TRACE("%p,%p\n", iface, policy);
974 if (!policy) return E_POINTER;
976 *policy = taskset->policy;
978 return S_OK;
981 static HRESULT WINAPI TaskSettings_put_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY policy)
983 TaskSettings *taskset = impl_from_ITaskSettings(iface);
985 TRACE("%p,%d\n", iface, policy);
987 taskset->policy = policy;
989 return S_OK;
992 static HRESULT WINAPI TaskSettings_get_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL *stop)
994 TaskSettings *taskset = impl_from_ITaskSettings(iface);
996 TRACE("%p,%p\n", iface, stop);
998 if (!stop) return E_POINTER;
1000 *stop = taskset->stop_if_going_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1002 return S_OK;
1005 static HRESULT WINAPI TaskSettings_put_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL stop)
1007 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1009 TRACE("%p,%d\n", iface, stop);
1011 taskset->stop_if_going_on_batteries = stop ? TRUE : FALSE;
1013 return S_OK;
1016 static HRESULT WINAPI TaskSettings_get_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL *disallow)
1018 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1020 TRACE("%p,%p\n", iface, disallow);
1022 if (!disallow) return E_POINTER;
1024 *disallow = taskset->disallow_start_if_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
1026 return S_OK;
1029 static HRESULT WINAPI TaskSettings_put_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL disallow)
1031 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1033 TRACE("%p,%d\n", iface, disallow);
1035 taskset->disallow_start_if_on_batteries = disallow ? TRUE : FALSE;
1037 return S_OK;
1040 static HRESULT WINAPI TaskSettings_get_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL *allow)
1042 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1044 TRACE("%p,%p\n", iface, allow);
1046 if (!allow) return E_POINTER;
1048 *allow = taskset->allow_hard_terminate ? VARIANT_TRUE : VARIANT_FALSE;
1050 return S_OK;
1053 static HRESULT WINAPI TaskSettings_put_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL allow)
1055 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1057 TRACE("%p,%d\n", iface, allow);
1059 taskset->allow_hard_terminate = allow ? TRUE : FALSE;
1061 return S_OK;
1064 static HRESULT WINAPI TaskSettings_get_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL *start)
1066 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1068 TRACE("%p,%p\n", iface, start);
1070 if (!start) return E_POINTER;
1072 *start = taskset->start_when_available ? VARIANT_TRUE : VARIANT_FALSE;
1074 return S_OK;
1077 static HRESULT WINAPI TaskSettings_put_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL start)
1079 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1081 TRACE("%p,%d\n", iface, start);
1083 taskset->start_when_available = start ? TRUE : FALSE;
1085 return S_OK;
1088 static HRESULT WINAPI TaskSettings_get_XmlText(ITaskSettings *iface, BSTR *xml)
1090 FIXME("%p,%p: stub\n", iface, xml);
1091 return E_NOTIMPL;
1094 static HRESULT WINAPI TaskSettings_put_XmlText(ITaskSettings *iface, BSTR xml)
1096 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
1097 return E_NOTIMPL;
1100 static HRESULT WINAPI TaskSettings_get_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL *run)
1102 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1104 TRACE("%p,%p\n", iface, run);
1106 if (!run) return E_POINTER;
1108 *run = taskset->run_only_if_network_available ? VARIANT_TRUE : VARIANT_FALSE;
1110 return S_OK;
1113 static HRESULT WINAPI TaskSettings_put_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL run)
1115 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1117 TRACE("%p,%d\n", iface, run);
1119 taskset->run_only_if_network_available = run ? TRUE : FALSE;
1121 return S_OK;
1124 static HRESULT WINAPI TaskSettings_get_ExecutionTimeLimit(ITaskSettings *iface, BSTR *limit)
1126 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1128 TRACE("%p,%p\n", iface, limit);
1130 if (!limit) return E_POINTER;
1132 if (!taskset->execution_time_limit)
1134 *limit = NULL;
1135 return S_OK;
1138 *limit = SysAllocString(taskset->execution_time_limit);
1139 if (!*limit) return E_OUTOFMEMORY;
1141 return S_OK;
1144 static HRESULT WINAPI TaskSettings_put_ExecutionTimeLimit(ITaskSettings *iface, BSTR limit)
1146 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1147 WCHAR *str = NULL;
1149 TRACE("%p,%s\n", iface, debugstr_w(limit));
1151 if (limit && !(str = heap_strdupW(limit))) return E_OUTOFMEMORY;
1152 heap_free(taskset->execution_time_limit);
1153 taskset->execution_time_limit = str;
1155 return S_OK;
1158 static HRESULT WINAPI TaskSettings_get_Enabled(ITaskSettings *iface, VARIANT_BOOL *enabled)
1160 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1162 TRACE("%p,%p\n", iface, enabled);
1164 if (!enabled) return E_POINTER;
1166 *enabled = taskset->enabled ? VARIANT_TRUE : VARIANT_FALSE;
1168 return S_OK;
1171 static HRESULT WINAPI TaskSettings_put_Enabled(ITaskSettings *iface, VARIANT_BOOL enabled)
1173 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1175 TRACE("%p,%d\n", iface, enabled);
1177 taskset->enabled = enabled ? TRUE : FALSE;
1179 return S_OK;
1182 static HRESULT WINAPI TaskSettings_get_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR *delay)
1184 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1186 TRACE("%p,%p\n", iface, delay);
1188 if (!delay) return E_POINTER;
1190 if (!taskset->delete_expired_task_after)
1192 *delay = NULL;
1193 return S_OK;
1196 *delay = SysAllocString(taskset->delete_expired_task_after);
1197 if (!*delay) return E_OUTOFMEMORY;
1199 return S_OK;
1202 static HRESULT WINAPI TaskSettings_put_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR delay)
1204 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1205 WCHAR *str = NULL;
1207 TRACE("%p,%s\n", iface, debugstr_w(delay));
1209 if (delay && !(str = heap_strdupW(delay))) return E_OUTOFMEMORY;
1210 heap_free(taskset->delete_expired_task_after);
1211 taskset->delete_expired_task_after = str;
1213 return S_OK;
1216 static HRESULT WINAPI TaskSettings_get_Priority(ITaskSettings *iface, INT *priority)
1218 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1220 TRACE("%p,%p\n", iface, priority);
1222 if (!priority) return E_POINTER;
1224 *priority = taskset->priority;
1226 return S_OK;
1229 static HRESULT WINAPI TaskSettings_put_Priority(ITaskSettings *iface, INT priority)
1231 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1233 TRACE("%p,%d\n", iface, priority);
1235 taskset->priority = priority;
1237 return S_OK;
1240 static HRESULT WINAPI TaskSettings_get_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY *level)
1242 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1244 TRACE("%p,%p\n", iface, level);
1246 if (!level) return E_POINTER;
1248 *level = taskset->compatibility;
1250 return S_OK;
1253 static HRESULT WINAPI TaskSettings_put_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY level)
1255 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1257 TRACE("%p,%d\n", iface, level);
1259 taskset->compatibility = level;
1261 return S_OK;
1264 static HRESULT WINAPI TaskSettings_get_Hidden(ITaskSettings *iface, VARIANT_BOOL *hidden)
1266 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1268 TRACE("%p,%p\n", iface, hidden);
1270 if (!hidden) return E_POINTER;
1272 *hidden = taskset->hidden ? VARIANT_TRUE : VARIANT_FALSE;
1274 return S_OK;
1277 static HRESULT WINAPI TaskSettings_put_Hidden(ITaskSettings *iface, VARIANT_BOOL hidden)
1279 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1281 TRACE("%p,%d\n", iface, hidden);
1283 taskset->hidden = hidden ? TRUE : FALSE;
1285 return S_OK;
1288 static HRESULT WINAPI TaskSettings_get_IdleSettings(ITaskSettings *iface, IIdleSettings **settings)
1290 FIXME("%p,%p: stub\n", iface, settings);
1291 return E_NOTIMPL;
1294 static HRESULT WINAPI TaskSettings_put_IdleSettings(ITaskSettings *iface, IIdleSettings *settings)
1296 FIXME("%p,%p: stub\n", iface, settings);
1297 return E_NOTIMPL;
1300 static HRESULT WINAPI TaskSettings_get_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL *run)
1302 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1304 TRACE("%p,%p\n", iface, run);
1306 if (!run) return E_POINTER;
1308 *run = taskset->run_only_if_idle ? VARIANT_TRUE : VARIANT_FALSE;
1310 return S_OK;
1313 static HRESULT WINAPI TaskSettings_put_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL run)
1315 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1317 TRACE("%p,%d\n", iface, run);
1319 taskset->run_only_if_idle = run ? TRUE : FALSE;
1321 return S_OK;
1324 static HRESULT WINAPI TaskSettings_get_WakeToRun(ITaskSettings *iface, VARIANT_BOOL *wake)
1326 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1328 TRACE("%p,%p\n", iface, wake);
1330 if (!wake) return E_POINTER;
1332 *wake = taskset->wake_to_run ? VARIANT_TRUE : VARIANT_FALSE;
1334 return S_OK;
1337 static HRESULT WINAPI TaskSettings_put_WakeToRun(ITaskSettings *iface, VARIANT_BOOL wake)
1339 TaskSettings *taskset = impl_from_ITaskSettings(iface);
1341 TRACE("%p,%d\n", iface, wake);
1343 taskset->wake_to_run = wake ? TRUE : FALSE;
1345 return S_OK;
1348 static HRESULT WINAPI TaskSettings_get_NetworkSettings(ITaskSettings *iface, INetworkSettings **settings)
1350 FIXME("%p,%p: stub\n", iface, settings);
1351 return E_NOTIMPL;
1354 static HRESULT WINAPI TaskSettings_put_NetworkSettings(ITaskSettings *iface, INetworkSettings *settings)
1356 FIXME("%p,%p: stub\n", iface, settings);
1357 return E_NOTIMPL;
1360 static const ITaskSettingsVtbl TaskSettings_vtbl =
1362 TaskSettings_QueryInterface,
1363 TaskSettings_AddRef,
1364 TaskSettings_Release,
1365 TaskSettings_GetTypeInfoCount,
1366 TaskSettings_GetTypeInfo,
1367 TaskSettings_GetIDsOfNames,
1368 TaskSettings_Invoke,
1369 TaskSettings_get_AllowDemandStart,
1370 TaskSettings_put_AllowDemandStart,
1371 TaskSettings_get_RestartInterval,
1372 TaskSettings_put_RestartInterval,
1373 TaskSettings_get_RestartCount,
1374 TaskSettings_put_RestartCount,
1375 TaskSettings_get_MultipleInstances,
1376 TaskSettings_put_MultipleInstances,
1377 TaskSettings_get_StopIfGoingOnBatteries,
1378 TaskSettings_put_StopIfGoingOnBatteries,
1379 TaskSettings_get_DisallowStartIfOnBatteries,
1380 TaskSettings_put_DisallowStartIfOnBatteries,
1381 TaskSettings_get_AllowHardTerminate,
1382 TaskSettings_put_AllowHardTerminate,
1383 TaskSettings_get_StartWhenAvailable,
1384 TaskSettings_put_StartWhenAvailable,
1385 TaskSettings_get_XmlText,
1386 TaskSettings_put_XmlText,
1387 TaskSettings_get_RunOnlyIfNetworkAvailable,
1388 TaskSettings_put_RunOnlyIfNetworkAvailable,
1389 TaskSettings_get_ExecutionTimeLimit,
1390 TaskSettings_put_ExecutionTimeLimit,
1391 TaskSettings_get_Enabled,
1392 TaskSettings_put_Enabled,
1393 TaskSettings_get_DeleteExpiredTaskAfter,
1394 TaskSettings_put_DeleteExpiredTaskAfter,
1395 TaskSettings_get_Priority,
1396 TaskSettings_put_Priority,
1397 TaskSettings_get_Compatibility,
1398 TaskSettings_put_Compatibility,
1399 TaskSettings_get_Hidden,
1400 TaskSettings_put_Hidden,
1401 TaskSettings_get_IdleSettings,
1402 TaskSettings_put_IdleSettings,
1403 TaskSettings_get_RunOnlyIfIdle,
1404 TaskSettings_put_RunOnlyIfIdle,
1405 TaskSettings_get_WakeToRun,
1406 TaskSettings_put_WakeToRun,
1407 TaskSettings_get_NetworkSettings,
1408 TaskSettings_put_NetworkSettings
1411 static HRESULT TaskSettings_create(ITaskSettings **obj)
1413 static const WCHAR exec_time_limit[] = { 'P','T','7','2','H',0 };
1414 TaskSettings *taskset;
1416 taskset = heap_alloc(sizeof(*taskset));
1417 if (!taskset) return E_OUTOFMEMORY;
1419 taskset->ITaskSettings_iface.lpVtbl = &TaskSettings_vtbl;
1420 taskset->ref = 1;
1421 /* set the defaults */
1422 taskset->restart_interval = NULL;
1423 taskset->execution_time_limit = heap_strdupW(exec_time_limit);
1424 taskset->delete_expired_task_after = NULL;
1425 taskset->restart_count = 0;
1426 taskset->priority = 7;
1427 taskset->policy = TASK_INSTANCES_IGNORE_NEW;
1428 taskset->compatibility = TASK_COMPATIBILITY_V2;
1429 taskset->allow_on_demand_start = TRUE;
1430 taskset->stop_if_going_on_batteries = TRUE;
1431 taskset->disallow_start_if_on_batteries = TRUE;
1432 taskset->allow_hard_terminate = TRUE;
1433 taskset->start_when_available = FALSE;
1434 taskset->run_only_if_network_available = FALSE;
1435 taskset->enabled = TRUE;
1436 taskset->hidden = FALSE;
1437 taskset->run_only_if_idle = FALSE;
1438 taskset->wake_to_run = FALSE;
1440 *obj = &taskset->ITaskSettings_iface;
1442 TRACE("created %p\n", *obj);
1444 return S_OK;
1447 typedef struct
1449 IPrincipal IPrincipal_iface;
1450 LONG ref;
1451 } Principal;
1453 static inline Principal *impl_from_IPrincipal(IPrincipal *iface)
1455 return CONTAINING_RECORD(iface, Principal, IPrincipal_iface);
1458 static ULONG WINAPI Principal_AddRef(IPrincipal *iface)
1460 Principal *principal = impl_from_IPrincipal(iface);
1461 return InterlockedIncrement(&principal->ref);
1464 static ULONG WINAPI Principal_Release(IPrincipal *iface)
1466 Principal *principal = impl_from_IPrincipal(iface);
1467 LONG ref = InterlockedDecrement(&principal->ref);
1469 if (!ref)
1471 TRACE("destroying %p\n", iface);
1472 heap_free(principal);
1475 return ref;
1478 static HRESULT WINAPI Principal_QueryInterface(IPrincipal *iface, REFIID riid, void **obj)
1480 if (!riid || !obj) return E_INVALIDARG;
1482 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1484 if (IsEqualGUID(riid, &IID_IPrincipal) ||
1485 IsEqualGUID(riid, &IID_IDispatch) ||
1486 IsEqualGUID(riid, &IID_IUnknown))
1488 IPrincipal_AddRef(iface);
1489 *obj = iface;
1490 return S_OK;
1493 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1494 *obj = NULL;
1495 return E_NOINTERFACE;
1498 static HRESULT WINAPI Principal_GetTypeInfoCount(IPrincipal *iface, UINT *count)
1500 FIXME("%p,%p: stub\n", iface, count);
1501 return E_NOTIMPL;
1504 static HRESULT WINAPI Principal_GetTypeInfo(IPrincipal *iface, UINT index, LCID lcid, ITypeInfo **info)
1506 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1507 return E_NOTIMPL;
1510 static HRESULT WINAPI Principal_GetIDsOfNames(IPrincipal *iface, REFIID riid, LPOLESTR *names,
1511 UINT count, LCID lcid, DISPID *dispid)
1513 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1514 return E_NOTIMPL;
1517 static HRESULT WINAPI Principal_Invoke(IPrincipal *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1518 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1520 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1521 params, result, excepinfo, argerr);
1522 return E_NOTIMPL;
1525 static HRESULT WINAPI Principal_get_Id(IPrincipal *iface, BSTR *id)
1527 FIXME("%p,%p: stub\n", iface, id);
1528 return E_NOTIMPL;
1531 static HRESULT WINAPI Principal_put_Id(IPrincipal *iface, BSTR id)
1533 FIXME("%p,%s: stub\n", iface, debugstr_w(id));
1534 return S_OK;
1537 static HRESULT WINAPI Principal_get_DisplayName(IPrincipal *iface, BSTR *name)
1539 FIXME("%p,%p: stub\n", iface, name);
1540 return E_NOTIMPL;
1543 static HRESULT WINAPI Principal_put_DisplayName(IPrincipal *iface, BSTR name)
1545 FIXME("%p,%s: stub\n", iface, debugstr_w(name));
1546 return E_NOTIMPL;
1549 static HRESULT WINAPI Principal_get_UserId(IPrincipal *iface, BSTR *user_id)
1551 FIXME("%p,%p: stub\n", iface, user_id);
1552 return E_NOTIMPL;
1555 static HRESULT WINAPI Principal_put_UserId(IPrincipal *iface, BSTR user_id)
1557 FIXME("%p,%s: stub\n", iface, debugstr_w(user_id));
1558 return S_OK;
1561 static HRESULT WINAPI Principal_get_LogonType(IPrincipal *iface, TASK_LOGON_TYPE *logon_type)
1563 FIXME("%p,%p: stub\n", iface, logon_type);
1564 return E_NOTIMPL;
1567 static HRESULT WINAPI Principal_put_LogonType(IPrincipal *iface, TASK_LOGON_TYPE logon_type)
1569 FIXME("%p,%u: stub\n", iface, logon_type);
1570 return E_NOTIMPL;
1573 static HRESULT WINAPI Principal_get_GroupId(IPrincipal *iface, BSTR *group_id)
1575 FIXME("%p,%p: stub\n", iface, group_id);
1576 return E_NOTIMPL;
1579 static HRESULT WINAPI Principal_put_GroupId(IPrincipal *iface, BSTR group_id)
1581 FIXME("%p,%s: stub\n", iface, debugstr_w(group_id));
1582 return E_NOTIMPL;
1585 static HRESULT WINAPI Principal_get_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE *run_level)
1587 FIXME("%p,%p: stub\n", iface, run_level);
1588 return E_NOTIMPL;
1591 static HRESULT WINAPI Principal_put_RunLevel(IPrincipal *iface, TASK_RUNLEVEL_TYPE run_level)
1593 FIXME("%p,%u: stub\n", iface, run_level);
1594 return E_NOTIMPL;
1597 static const IPrincipalVtbl Principal_vtbl =
1599 Principal_QueryInterface,
1600 Principal_AddRef,
1601 Principal_Release,
1602 Principal_GetTypeInfoCount,
1603 Principal_GetTypeInfo,
1604 Principal_GetIDsOfNames,
1605 Principal_Invoke,
1606 Principal_get_Id,
1607 Principal_put_Id,
1608 Principal_get_DisplayName,
1609 Principal_put_DisplayName,
1610 Principal_get_UserId,
1611 Principal_put_UserId,
1612 Principal_get_LogonType,
1613 Principal_put_LogonType,
1614 Principal_get_GroupId,
1615 Principal_put_GroupId,
1616 Principal_get_RunLevel,
1617 Principal_put_RunLevel
1620 static HRESULT Principal_create(IPrincipal **obj)
1622 Principal *principal;
1624 principal = heap_alloc(sizeof(*principal));
1625 if (!principal) return E_OUTOFMEMORY;
1627 principal->IPrincipal_iface.lpVtbl = &Principal_vtbl;
1628 principal->ref = 1;
1630 *obj = &principal->IPrincipal_iface;
1632 TRACE("created %p\n", *obj);
1634 return S_OK;
1637 typedef struct
1639 IExecAction IExecAction_iface;
1640 LONG ref;
1641 WCHAR *path;
1642 } ExecAction;
1644 static inline ExecAction *impl_from_IExecAction(IExecAction *iface)
1646 return CONTAINING_RECORD(iface, ExecAction, IExecAction_iface);
1649 static ULONG WINAPI ExecAction_AddRef(IExecAction *iface)
1651 ExecAction *action = impl_from_IExecAction(iface);
1652 return InterlockedIncrement(&action->ref);
1655 static ULONG WINAPI ExecAction_Release(IExecAction *iface)
1657 ExecAction *action = impl_from_IExecAction(iface);
1658 LONG ref = InterlockedDecrement(&action->ref);
1660 if (!ref)
1662 TRACE("destroying %p\n", iface);
1663 heap_free(action->path);
1664 heap_free(action);
1667 return ref;
1670 static HRESULT WINAPI ExecAction_QueryInterface(IExecAction *iface, REFIID riid, void **obj)
1672 if (!riid || !obj) return E_INVALIDARG;
1674 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1676 if (IsEqualGUID(riid, &IID_IExecAction) ||
1677 IsEqualGUID(riid, &IID_IAction) ||
1678 IsEqualGUID(riid, &IID_IDispatch) ||
1679 IsEqualGUID(riid, &IID_IUnknown))
1681 IExecAction_AddRef(iface);
1682 *obj = iface;
1683 return S_OK;
1686 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1687 *obj = NULL;
1688 return E_NOINTERFACE;
1691 static HRESULT WINAPI ExecAction_GetTypeInfoCount(IExecAction *iface, UINT *count)
1693 FIXME("%p,%p: stub\n", iface, count);
1694 return E_NOTIMPL;
1697 static HRESULT WINAPI ExecAction_GetTypeInfo(IExecAction *iface, UINT index, LCID lcid, ITypeInfo **info)
1699 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1700 return E_NOTIMPL;
1703 static HRESULT WINAPI ExecAction_GetIDsOfNames(IExecAction *iface, REFIID riid, LPOLESTR *names,
1704 UINT count, LCID lcid, DISPID *dispid)
1706 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1707 return E_NOTIMPL;
1710 static HRESULT WINAPI ExecAction_Invoke(IExecAction *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1711 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1713 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1714 params, result, excepinfo, argerr);
1715 return E_NOTIMPL;
1718 static HRESULT WINAPI ExecAction_get_Id(IExecAction *iface, BSTR *id)
1720 FIXME("%p,%p: stub\n", iface, id);
1721 return E_NOTIMPL;
1724 static HRESULT WINAPI ExecAction_put_Id(IExecAction *iface, BSTR id)
1726 FIXME("%p,%s: stub\n", iface, debugstr_w(id));
1727 return E_NOTIMPL;
1730 static HRESULT WINAPI ExecAction_get_Type(IExecAction *iface, TASK_ACTION_TYPE *type)
1732 TRACE("%p,%p\n", iface, type);
1734 if (!type) return E_POINTER;
1736 *type = TASK_ACTION_EXEC;
1738 return S_OK;
1741 static HRESULT WINAPI ExecAction_get_Path(IExecAction *iface, BSTR *path)
1743 ExecAction *action = impl_from_IExecAction(iface);
1745 TRACE("%p,%p\n", iface, path);
1747 if (!path) return E_POINTER;
1749 if (!action->path)
1751 *path = NULL;
1752 return S_OK;
1755 if (!(*path = SysAllocString(action->path))) return E_OUTOFMEMORY;
1756 return S_OK;
1759 static HRESULT WINAPI ExecAction_put_Path(IExecAction *iface, BSTR path)
1761 ExecAction *action = impl_from_IExecAction(iface);
1762 WCHAR *str = NULL;
1764 TRACE("%p,%s\n", iface, debugstr_w(path));
1766 if (path && !(str = heap_strdupW((path)))) return E_OUTOFMEMORY;
1767 heap_free(action->path);
1768 action->path = str;
1770 return S_OK;
1773 static HRESULT WINAPI ExecAction_get_Arguments(IExecAction *iface, BSTR *arguments)
1775 FIXME("%p,%p: stub\n", iface, arguments);
1776 return E_NOTIMPL;
1779 static HRESULT WINAPI ExecAction_put_Arguments(IExecAction *iface, BSTR arguments)
1781 FIXME("%p,%s: stub\n", iface, debugstr_w(arguments));
1782 return S_OK;
1785 static HRESULT WINAPI ExecAction_get_WorkingDirectory(IExecAction *iface, BSTR *directory)
1787 FIXME("%p,%p: stub\n", iface, directory);
1788 return E_NOTIMPL;
1791 static HRESULT WINAPI ExecAction_put_WorkingDirectory(IExecAction *iface, BSTR directory)
1793 FIXME("%p,%s: stub\n", iface, debugstr_w(directory));
1794 return E_NOTIMPL;
1797 static const IExecActionVtbl Action_vtbl =
1799 ExecAction_QueryInterface,
1800 ExecAction_AddRef,
1801 ExecAction_Release,
1802 ExecAction_GetTypeInfoCount,
1803 ExecAction_GetTypeInfo,
1804 ExecAction_GetIDsOfNames,
1805 ExecAction_Invoke,
1806 ExecAction_get_Id,
1807 ExecAction_put_Id,
1808 ExecAction_get_Type,
1809 ExecAction_get_Path,
1810 ExecAction_put_Path,
1811 ExecAction_get_Arguments,
1812 ExecAction_put_Arguments,
1813 ExecAction_get_WorkingDirectory,
1814 ExecAction_put_WorkingDirectory
1817 static HRESULT ExecAction_create(IExecAction **obj)
1819 ExecAction *action;
1821 action = heap_alloc(sizeof(*action));
1822 if (!action) return E_OUTOFMEMORY;
1824 action->IExecAction_iface.lpVtbl = &Action_vtbl;
1825 action->ref = 1;
1826 action->path = NULL;
1828 *obj = &action->IExecAction_iface;
1830 TRACE("created %p\n", *obj);
1832 return S_OK;
1835 typedef struct
1837 IActionCollection IActionCollection_iface;
1838 LONG ref;
1839 } Actions;
1841 static inline Actions *impl_from_IActionCollection(IActionCollection *iface)
1843 return CONTAINING_RECORD(iface, Actions, IActionCollection_iface);
1846 static ULONG WINAPI Actions_AddRef(IActionCollection *iface)
1848 Actions *actions = impl_from_IActionCollection(iface);
1849 return InterlockedIncrement(&actions->ref);
1852 static ULONG WINAPI Actions_Release(IActionCollection *iface)
1854 Actions *actions = impl_from_IActionCollection(iface);
1855 LONG ref = InterlockedDecrement(&actions->ref);
1857 if (!ref)
1859 TRACE("destroying %p\n", iface);
1860 heap_free(actions);
1863 return ref;
1866 static HRESULT WINAPI Actions_QueryInterface(IActionCollection *iface, REFIID riid, void **obj)
1868 if (!riid || !obj) return E_INVALIDARG;
1870 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
1872 if (IsEqualGUID(riid, &IID_IActionCollection) ||
1873 IsEqualGUID(riid, &IID_IDispatch) ||
1874 IsEqualGUID(riid, &IID_IUnknown))
1876 IActionCollection_AddRef(iface);
1877 *obj = iface;
1878 return S_OK;
1881 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
1882 *obj = NULL;
1883 return E_NOINTERFACE;
1886 static HRESULT WINAPI Actions_GetTypeInfoCount(IActionCollection *iface, UINT *count)
1888 FIXME("%p,%p: stub\n", iface, count);
1889 return E_NOTIMPL;
1892 static HRESULT WINAPI Actions_GetTypeInfo(IActionCollection *iface, UINT index, LCID lcid, ITypeInfo **info)
1894 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
1895 return E_NOTIMPL;
1898 static HRESULT WINAPI Actions_GetIDsOfNames(IActionCollection *iface, REFIID riid, LPOLESTR *names,
1899 UINT count, LCID lcid, DISPID *dispid)
1901 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
1902 return E_NOTIMPL;
1905 static HRESULT WINAPI Actions_Invoke(IActionCollection *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
1906 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
1908 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
1909 params, result, excepinfo, argerr);
1910 return E_NOTIMPL;
1913 static HRESULT WINAPI Actions_get_Count(IActionCollection *iface, LONG *count)
1915 FIXME("%p,%p: stub\n", iface, count);
1916 return E_NOTIMPL;
1919 static HRESULT WINAPI Actions_get_Item(IActionCollection *iface, LONG index, IAction **action)
1921 FIXME("%p,%d,%p: stub\n", iface, index, action);
1922 return E_NOTIMPL;
1925 static HRESULT WINAPI Actions_get__NewEnum(IActionCollection *iface, IUnknown **penum)
1927 FIXME("%p,%p: stub\n", iface, penum);
1928 return E_NOTIMPL;
1931 static HRESULT WINAPI Actions_get_XmlText(IActionCollection *iface, BSTR *xml)
1933 FIXME("%p,%p: stub\n", iface, xml);
1934 return E_NOTIMPL;
1937 static HRESULT WINAPI Actions_put_XmlText(IActionCollection *iface, BSTR xml)
1939 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
1940 return E_NOTIMPL;
1943 static HRESULT WINAPI Actions_Create(IActionCollection *iface, TASK_ACTION_TYPE type, IAction **action)
1945 TRACE("%p,%u,%p\n", iface, type, action);
1947 switch (type)
1949 case TASK_ACTION_EXEC:
1950 return ExecAction_create((IExecAction **)action);
1952 default:
1953 FIXME("unimplemented type %u\n", type);
1954 return E_NOTIMPL;
1958 static HRESULT WINAPI Actions_Remove(IActionCollection *iface, VARIANT index)
1960 FIXME("%p,%s: stub\n", iface, debugstr_variant(&index));
1961 return E_NOTIMPL;
1964 static HRESULT WINAPI Actions_Clear(IActionCollection *iface)
1966 FIXME("%p: stub\n", iface);
1967 return E_NOTIMPL;
1970 static HRESULT WINAPI Actions_get_Context(IActionCollection *iface, BSTR *ctx)
1972 FIXME("%p,%p: stub\n", iface, ctx);
1973 return E_NOTIMPL;
1976 static HRESULT WINAPI Actions_put_Context(IActionCollection *iface, BSTR ctx)
1978 FIXME("%p,%s: stub\n", iface, debugstr_w(ctx));
1979 return S_OK;
1982 static const IActionCollectionVtbl Actions_vtbl =
1984 Actions_QueryInterface,
1985 Actions_AddRef,
1986 Actions_Release,
1987 Actions_GetTypeInfoCount,
1988 Actions_GetTypeInfo,
1989 Actions_GetIDsOfNames,
1990 Actions_Invoke,
1991 Actions_get_Count,
1992 Actions_get_Item,
1993 Actions_get__NewEnum,
1994 Actions_get_XmlText,
1995 Actions_put_XmlText,
1996 Actions_Create,
1997 Actions_Remove,
1998 Actions_Clear,
1999 Actions_get_Context,
2000 Actions_put_Context
2003 static HRESULT Actions_create(IActionCollection **obj)
2005 Actions *actions;
2007 actions = heap_alloc(sizeof(*actions));
2008 if (!actions) return E_OUTOFMEMORY;
2010 actions->IActionCollection_iface.lpVtbl = &Actions_vtbl;
2011 actions->ref = 1;
2013 *obj = &actions->IActionCollection_iface;
2015 TRACE("created %p\n", *obj);
2017 return S_OK;
2020 typedef struct
2022 ITaskDefinition ITaskDefinition_iface;
2023 LONG ref;
2024 IRegistrationInfo *reginfo;
2025 ITaskSettings *taskset;
2026 ITriggerCollection *triggers;
2027 IPrincipal *principal;
2028 IActionCollection *actions;
2029 } TaskDefinition;
2031 static inline TaskDefinition *impl_from_ITaskDefinition(ITaskDefinition *iface)
2033 return CONTAINING_RECORD(iface, TaskDefinition, ITaskDefinition_iface);
2036 static ULONG WINAPI TaskDefinition_AddRef(ITaskDefinition *iface)
2038 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2039 return InterlockedIncrement(&taskdef->ref);
2042 static ULONG WINAPI TaskDefinition_Release(ITaskDefinition *iface)
2044 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2045 LONG ref = InterlockedDecrement(&taskdef->ref);
2047 if (!ref)
2049 TRACE("destroying %p\n", iface);
2051 if (taskdef->reginfo)
2052 IRegistrationInfo_Release(taskdef->reginfo);
2053 if (taskdef->taskset)
2054 ITaskSettings_Release(taskdef->taskset);
2055 if (taskdef->triggers)
2056 ITriggerCollection_Release(taskdef->triggers);
2057 if (taskdef->principal)
2058 IPrincipal_Release(taskdef->principal);
2059 if (taskdef->actions)
2060 IActionCollection_Release(taskdef->actions);
2062 heap_free(taskdef);
2065 return ref;
2068 static HRESULT WINAPI TaskDefinition_QueryInterface(ITaskDefinition *iface, REFIID riid, void **obj)
2070 if (!riid || !obj) return E_INVALIDARG;
2072 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
2074 if (IsEqualGUID(riid, &IID_ITaskDefinition) ||
2075 IsEqualGUID(riid, &IID_IDispatch) ||
2076 IsEqualGUID(riid, &IID_IUnknown))
2078 ITaskDefinition_AddRef(iface);
2079 *obj = iface;
2080 return S_OK;
2083 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
2084 *obj = NULL;
2085 return E_NOINTERFACE;
2088 static HRESULT WINAPI TaskDefinition_GetTypeInfoCount(ITaskDefinition *iface, UINT *count)
2090 FIXME("%p,%p: stub\n", iface, count);
2091 return E_NOTIMPL;
2094 static HRESULT WINAPI TaskDefinition_GetTypeInfo(ITaskDefinition *iface, UINT index, LCID lcid, ITypeInfo **info)
2096 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
2097 return E_NOTIMPL;
2100 static HRESULT WINAPI TaskDefinition_GetIDsOfNames(ITaskDefinition *iface, REFIID riid, LPOLESTR *names,
2101 UINT count, LCID lcid, DISPID *dispid)
2103 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
2104 return E_NOTIMPL;
2107 static HRESULT WINAPI TaskDefinition_Invoke(ITaskDefinition *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
2108 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
2110 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
2111 params, result, excepinfo, argerr);
2112 return E_NOTIMPL;
2115 static HRESULT WINAPI TaskDefinition_get_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo **info)
2117 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2118 HRESULT hr;
2120 TRACE("%p,%p\n", iface, info);
2122 if (!info) return E_POINTER;
2124 if (!taskdef->reginfo)
2126 hr = RegistrationInfo_create(&taskdef->reginfo);
2127 if (hr != S_OK) return hr;
2130 IRegistrationInfo_AddRef(taskdef->reginfo);
2131 *info = taskdef->reginfo;
2133 return S_OK;
2136 static HRESULT WINAPI TaskDefinition_put_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo *info)
2138 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2140 TRACE("%p,%p\n", iface, info);
2142 if (!info) return E_POINTER;
2144 if (taskdef->reginfo)
2145 IRegistrationInfo_Release(taskdef->reginfo);
2147 IRegistrationInfo_AddRef(info);
2148 taskdef->reginfo = info;
2150 return S_OK;
2153 static HRESULT WINAPI TaskDefinition_get_Triggers(ITaskDefinition *iface, ITriggerCollection **triggers)
2155 TaskDefinition *This = impl_from_ITaskDefinition(iface);
2157 TRACE("%p,%p\n", This, triggers);
2159 if (!This->triggers)
2161 trigger_collection *collection;
2163 collection = heap_alloc(sizeof(*collection));
2164 if (!collection) return E_OUTOFMEMORY;
2166 collection->ITriggerCollection_iface.lpVtbl = &TriggerCollection_vtbl;
2167 collection->ref = 1;
2168 This->triggers = &collection->ITriggerCollection_iface;
2171 ITriggerCollection_AddRef(*triggers = This->triggers);
2172 return S_OK;
2175 static HRESULT WINAPI TaskDefinition_put_Triggers(ITaskDefinition *iface, ITriggerCollection *triggers)
2177 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2179 TRACE("%p,%p\n", iface, triggers);
2181 if (!triggers) return E_POINTER;
2183 if (taskdef->triggers)
2184 ITriggerCollection_Release(taskdef->triggers);
2186 ITriggerCollection_AddRef(triggers);
2187 taskdef->triggers = triggers;
2189 return S_OK;
2192 static HRESULT WINAPI TaskDefinition_get_Settings(ITaskDefinition *iface, ITaskSettings **settings)
2194 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2195 HRESULT hr;
2197 TRACE("%p,%p\n", iface, settings);
2199 if (!settings) return E_POINTER;
2201 if (!taskdef->taskset)
2203 hr = TaskSettings_create(&taskdef->taskset);
2204 if (hr != S_OK) return hr;
2207 ITaskSettings_AddRef(taskdef->taskset);
2208 *settings = taskdef->taskset;
2210 return S_OK;
2213 static HRESULT WINAPI TaskDefinition_put_Settings(ITaskDefinition *iface, ITaskSettings *settings)
2215 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2217 TRACE("%p,%p\n", iface, settings);
2219 if (!settings) return E_POINTER;
2221 if (taskdef->taskset)
2222 ITaskSettings_Release(taskdef->taskset);
2224 ITaskSettings_AddRef(settings);
2225 taskdef->taskset = settings;
2227 return S_OK;
2230 static HRESULT WINAPI TaskDefinition_get_Data(ITaskDefinition *iface, BSTR *data)
2232 FIXME("%p,%p: stub\n", iface, data);
2233 return E_NOTIMPL;
2236 static HRESULT WINAPI TaskDefinition_put_Data(ITaskDefinition *iface, BSTR data)
2238 FIXME("%p,%p: stub\n", iface, data);
2239 return E_NOTIMPL;
2242 static HRESULT WINAPI TaskDefinition_get_Principal(ITaskDefinition *iface, IPrincipal **principal)
2244 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2245 HRESULT hr;
2247 TRACE("%p,%p\n", iface, principal);
2249 if (!principal) return E_POINTER;
2251 if (!taskdef->principal)
2253 hr = Principal_create(&taskdef->principal);
2254 if (hr != S_OK) return hr;
2257 IPrincipal_AddRef(taskdef->principal);
2258 *principal = taskdef->principal;
2260 return S_OK;
2263 static HRESULT WINAPI TaskDefinition_put_Principal(ITaskDefinition *iface, IPrincipal *principal)
2265 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2267 TRACE("%p,%p\n", iface, principal);
2269 if (!principal) return E_POINTER;
2271 if (taskdef->principal)
2272 IPrincipal_Release(taskdef->principal);
2274 IPrincipal_AddRef(principal);
2275 taskdef->principal = principal;
2277 return S_OK;
2280 static HRESULT WINAPI TaskDefinition_get_Actions(ITaskDefinition *iface, IActionCollection **actions)
2282 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2283 HRESULT hr;
2285 TRACE("%p,%p\n", iface, actions);
2287 if (!actions) return E_POINTER;
2289 if (!taskdef->actions)
2291 hr = Actions_create(&taskdef->actions);
2292 if (hr != S_OK) return hr;
2295 IActionCollection_AddRef(taskdef->actions);
2296 *actions = taskdef->actions;
2298 return S_OK;
2301 static HRESULT WINAPI TaskDefinition_put_Actions(ITaskDefinition *iface, IActionCollection *actions)
2303 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2305 TRACE("%p,%p\n", iface, actions);
2307 if (!actions) return E_POINTER;
2309 if (taskdef->actions)
2310 IActionCollection_Release(taskdef->actions);
2312 IActionCollection_AddRef(actions);
2313 taskdef->actions = actions;
2315 return S_OK;
2318 static const WCHAR Task[] = {'T','a','s','k',0};
2319 static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
2320 static const WCHAR v1_0[] = {'1','.','0',0};
2321 static const WCHAR v1_1[] = {'1','.','1',0};
2322 static const WCHAR v1_2[] = {'1','.','2',0};
2323 static const WCHAR v1_3[] = {'1','.','3',0};
2324 static const WCHAR xmlns[] = {'x','m','l','n','s',0};
2325 static const WCHAR task_ns[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','w','i','n','d','o','w','s','/','2','0','0','4','/','0','2','/','m','i','t','/','t','a','s','k',0};
2326 static const WCHAR RegistrationInfo[] = {'R','e','g','i','s','t','r','a','t','i','o','n','I','n','f','o',0};
2327 static const WCHAR Author[] = {'A','u','t','h','o','r',0};
2328 static const WCHAR Description[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
2329 static const WCHAR Source[] = {'S','o','u','r','c','e',0};
2330 static const WCHAR Date[] = {'D','a','t','e',0};
2331 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
2332 static const WCHAR Documentation[] = {'D','o','c','u','m','e','n','t','a','t','i','o','n',0};
2333 static const WCHAR URI[] = {'U','R','I',0};
2334 static const WCHAR SecurityDescriptor[] = {'S','e','c','u','r','i','t','y','D','e','s','c','r','i','p','t','o','r',0};
2335 static const WCHAR Settings[] = {'S','e','t','t','i','n','g','s',0};
2336 static const WCHAR Triggers[] = {'T','r','i','g','g','e','r','s',0};
2337 static const WCHAR Principals[] = {'P','r','i','n','c','i','p','a','l','s',0};
2338 static const WCHAR principalW[] = {'P','r','i','n','c','i','p','a','l',0};
2339 static const WCHAR id[] = {'i','d',0};
2340 static const WCHAR UserId[] = {'U','s','e','r','I','d',0};
2341 static const WCHAR LogonType[] = {'L','o','g','o','n','T','y','p','e',0};
2342 static const WCHAR GroupId[] = {'G','r','o','u','p','I','d',0};
2343 static const WCHAR DisplayName[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
2344 static const WCHAR HighestAvailable[] = {'H','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
2345 static const WCHAR Password[] = {'P','a','s','s','w','o','r','d',0};
2346 static const WCHAR S4U[] = {'S','4','U',0};
2347 static const WCHAR InteractiveToken[] = {'I','n','t','e','r','a','c','t','i','v','e','T','o','k','e','n',0};
2348 static const WCHAR RunLevel[] = {'R','u','n','L','e','v','e','l',0};
2349 static const WCHAR LeastPrivilege[] = {'L','e','a','s','t','P','r','i','v','i','l','e','g','e',0};
2350 static const WCHAR actionsW[] = {'A','c','t','i','o','n','s',0};
2351 static const WCHAR Exec[] = {'E','x','e','c',0};
2352 static const WCHAR MultipleInstancesPolicy[] = {'M','u','l','t','i','p','l','e','I','n','s','t','a','n','c','e','s','P','o','l','i','c','y',0};
2353 static const WCHAR IgnoreNew[] = {'I','g','n','o','r','e','N','e','w',0};
2354 static const WCHAR DisallowStartIfOnBatteries[] = {'D','i','s','a','l','l','o','w','S','t','a','r','t','I','f','O','n','B','a','t','t','e','r','i','e','s',0};
2355 static const WCHAR AllowStartOnDemand[] = {'A','l','l','o','w','S','t','a','r','t','O','n','D','e','m','a','n','d',0};
2356 static const WCHAR StopIfGoingOnBatteries[] = {'S','t','o','p','I','f','G','o','i','n','g','O','n','B','a','t','t','e','r','i','e','s',0};
2357 static const WCHAR AllowHardTerminate[] = {'A','l','l','o','w','H','a','r','d','T','e','r','m','i','n','a','t','e',0};
2358 static const WCHAR StartWhenAvailable[] = {'S','t','a','r','t','W','h','e','n','A','v','a','i','l','a','b','l','e',0};
2359 static const WCHAR RunOnlyIfNetworkAvailable[] = {'R','u','n','O','n','l','y','I','f','N','e','t','w','o','r','k','A','v','a','i','l','a','b','l','e',0};
2360 static const WCHAR Enabled[] = {'E','n','a','b','l','e','d',0};
2361 static const WCHAR Hidden[] = {'H','i','d','d','e','n',0};
2362 static const WCHAR RunOnlyIfIdle[] = {'R','u','n','O','n','l','y','I','f','I','d','l','e',0};
2363 static const WCHAR WakeToRun[] = {'W','a','k','e','T','o','R','u','n',0};
2364 static const WCHAR ExecutionTimeLimit[] = {'E','x','e','c','u','t','i','o','n','T','i','m','e','L','i','m','i','t',0};
2365 static const WCHAR Priority[] = {'P','r','i','o','r','i','t','y',0};
2366 static const WCHAR IdleSettings[] = {'I','d','l','e','S','e','t','t','i','n','g','s',0};
2368 static int xml_indent;
2370 static inline void push_indent(void)
2372 xml_indent += 2;
2375 static inline void pop_indent(void)
2377 xml_indent -= 2;
2380 static inline HRESULT write_stringW(IStream *stream, const WCHAR *str)
2382 return IStream_Write(stream, str, lstrlenW(str) * sizeof(WCHAR), NULL);
2385 static void write_indent(IStream *stream)
2387 static const WCHAR spacesW[] = {' ',' ',0};
2388 int i;
2389 for (i = 0; i < xml_indent; i += 2)
2390 write_stringW(stream, spacesW);
2393 static const WCHAR start_element[] = {'<',0};
2394 static const WCHAR start_end_element[] = {'<','/',0};
2395 static const WCHAR close_element[] = {'>',0};
2396 static const WCHAR end_empty_element[] = {'/','>',0};
2397 static const WCHAR eol[] = {'\n',0};
2398 static const WCHAR spaceW[] = {' ',0};
2399 static const WCHAR equalW[] = {'=',0};
2400 static const WCHAR quoteW[] = {'"',0};
2402 static inline HRESULT write_empty_element(IStream *stream, const WCHAR *name)
2404 write_indent(stream);
2405 write_stringW(stream, start_element);
2406 write_stringW(stream, name);
2407 write_stringW(stream, end_empty_element);
2408 return write_stringW(stream, eol);
2411 static inline HRESULT write_element(IStream *stream, const WCHAR *name)
2413 write_indent(stream);
2414 write_stringW(stream, start_element);
2415 write_stringW(stream, name);
2416 write_stringW(stream, close_element);
2417 return write_stringW(stream, eol);
2420 static inline HRESULT write_element_end(IStream *stream, const WCHAR *name)
2422 write_indent(stream);
2423 write_stringW(stream, start_end_element);
2424 write_stringW(stream, name);
2425 write_stringW(stream, close_element);
2426 return write_stringW(stream, eol);
2429 static inline HRESULT write_text_value(IStream *stream, const WCHAR *name, const WCHAR *value)
2431 write_indent(stream);
2432 write_stringW(stream, start_element);
2433 write_stringW(stream, name);
2434 write_stringW(stream, close_element);
2435 write_stringW(stream, value);
2436 write_stringW(stream, start_end_element);
2437 write_stringW(stream, name);
2438 write_stringW(stream, close_element);
2439 return write_stringW(stream, eol);
2442 static HRESULT write_task_attributes(IStream *stream, ITaskDefinition *taskdef)
2444 HRESULT hr;
2445 ITaskSettings *taskset;
2446 TASK_COMPATIBILITY level;
2447 const WCHAR *compatibility;
2449 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
2450 if (hr != S_OK) return hr;
2452 hr = ITaskSettings_get_Compatibility(taskset, &level);
2453 if (hr != S_OK) level = TASK_COMPATIBILITY_V2_1;
2455 ITaskSettings_Release(taskset);
2457 switch (level)
2459 case TASK_COMPATIBILITY_AT:
2460 compatibility = v1_0;
2461 break;
2462 case TASK_COMPATIBILITY_V1:
2463 compatibility = v1_1;
2464 break;
2465 case TASK_COMPATIBILITY_V2:
2466 compatibility = v1_2;
2467 break;
2468 default:
2469 compatibility = v1_3;
2470 break;
2473 write_stringW(stream, start_element);
2474 write_stringW(stream, Task);
2475 write_stringW(stream, spaceW);
2476 write_stringW(stream, version);
2477 write_stringW(stream, equalW);
2478 write_stringW(stream, quoteW);
2479 write_stringW(stream, compatibility);
2480 write_stringW(stream, quoteW);
2481 write_stringW(stream, spaceW);
2482 write_stringW(stream, xmlns);
2483 write_stringW(stream, equalW);
2484 write_stringW(stream, quoteW);
2485 write_stringW(stream, task_ns);
2486 write_stringW(stream, quoteW);
2487 write_stringW(stream, close_element);
2488 return write_stringW(stream, eol);
2491 static HRESULT write_registration_info(IStream *stream, IRegistrationInfo *reginfo)
2493 HRESULT hr;
2494 BSTR bstr;
2495 VARIANT var;
2497 if (!reginfo)
2498 return write_empty_element(stream, RegistrationInfo);
2500 hr = write_element(stream, RegistrationInfo);
2501 if (hr != S_OK) return hr;
2503 push_indent();
2505 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
2506 if (hr == S_OK && bstr)
2508 hr = write_text_value(stream, Source, bstr);
2509 SysFreeString(bstr);
2510 if (hr != S_OK) return hr;
2512 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
2513 if (hr == S_OK && bstr)
2515 hr = write_text_value(stream, Date, bstr);
2516 SysFreeString(bstr);
2517 if (hr != S_OK) return hr;
2519 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
2520 if (hr == S_OK && bstr)
2522 hr = write_text_value(stream, Author, bstr);
2523 SysFreeString(bstr);
2524 if (hr != S_OK) return hr;
2526 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
2527 if (hr == S_OK && bstr)
2529 hr = write_text_value(stream, Version, bstr);
2530 SysFreeString(bstr);
2531 if (hr != S_OK) return hr;
2533 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
2534 if (hr == S_OK && bstr)
2536 hr = write_text_value(stream, Description, bstr);
2537 SysFreeString(bstr);
2538 if (hr != S_OK) return hr;
2540 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
2541 if (hr == S_OK && bstr)
2543 hr = write_text_value(stream, Documentation, bstr);
2544 SysFreeString(bstr);
2545 if (hr != S_OK) return hr;
2547 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
2548 if (hr == S_OK && bstr)
2550 hr = write_text_value(stream, URI, bstr);
2551 SysFreeString(bstr);
2552 if (hr != S_OK) return hr;
2554 hr = IRegistrationInfo_get_SecurityDescriptor(reginfo, &var);
2555 if (hr == S_OK)
2557 if (V_VT(&var) == VT_BSTR)
2559 hr = write_text_value(stream, SecurityDescriptor, V_BSTR(&var));
2560 VariantClear(&var);
2561 if (hr != S_OK) return hr;
2563 else
2564 FIXME("SecurityInfo variant type %d is not supported\n", V_VT(&var));
2567 pop_indent();
2569 return write_element_end(stream, RegistrationInfo);
2572 static HRESULT write_principal(IStream *stream, IPrincipal *principal)
2574 HRESULT hr;
2575 BSTR bstr;
2576 TASK_LOGON_TYPE logon;
2577 TASK_RUNLEVEL_TYPE level;
2579 if (!principal)
2580 return write_empty_element(stream, Principals);
2582 hr = write_element(stream, Principals);
2583 if (hr != S_OK) return hr;
2585 push_indent();
2587 hr = IPrincipal_get_Id(principal, &bstr);
2588 if (hr == S_OK)
2590 write_indent(stream);
2591 write_stringW(stream, start_element);
2592 write_stringW(stream, principalW);
2593 write_stringW(stream, spaceW);
2594 write_stringW(stream, id);
2595 write_stringW(stream, equalW);
2596 write_stringW(stream, quoteW);
2597 write_stringW(stream, bstr);
2598 write_stringW(stream, quoteW);
2599 write_stringW(stream, close_element);
2600 write_stringW(stream, eol);
2601 SysFreeString(bstr);
2603 else
2604 write_element(stream, principalW);
2606 push_indent();
2608 hr = IPrincipal_get_GroupId(principal, &bstr);
2609 if (hr == S_OK)
2611 hr = write_text_value(stream, GroupId, bstr);
2612 SysFreeString(bstr);
2613 if (hr != S_OK) return hr;
2615 hr = IPrincipal_get_DisplayName(principal, &bstr);
2616 if (hr == S_OK)
2618 hr = write_text_value(stream, DisplayName, bstr);
2619 SysFreeString(bstr);
2620 if (hr != S_OK) return hr;
2622 hr = IPrincipal_get_UserId(principal, &bstr);
2623 if (hr == S_OK && lstrlenW(bstr))
2625 hr = write_text_value(stream, UserId, bstr);
2626 SysFreeString(bstr);
2627 if (hr != S_OK) return hr;
2629 hr = IPrincipal_get_RunLevel(principal, &level);
2630 if (hr == S_OK)
2632 const WCHAR *level_str = NULL;
2634 switch (level)
2636 case TASK_RUNLEVEL_HIGHEST:
2637 level_str = HighestAvailable;
2638 break;
2639 case TASK_RUNLEVEL_LUA:
2640 level_str = LeastPrivilege;
2641 break;
2642 default:
2643 FIXME("Principal run level %d\n", level);
2644 break;
2647 if (level_str)
2649 hr = write_text_value(stream, RunLevel, level_str);
2650 if (hr != S_OK) return hr;
2653 hr = IPrincipal_get_LogonType(principal, &logon);
2654 if (hr == S_OK)
2656 const WCHAR *logon_str = NULL;
2658 switch (logon)
2660 case TASK_LOGON_PASSWORD:
2661 logon_str = Password;
2662 break;
2663 case TASK_LOGON_S4U:
2664 logon_str = S4U;
2665 break;
2666 case TASK_LOGON_INTERACTIVE_TOKEN:
2667 logon_str = InteractiveToken;
2668 break;
2669 default:
2670 FIXME("Principal logon type %d\n", logon);
2671 break;
2674 if (logon_str)
2676 hr = write_text_value(stream, LogonType, logon_str);
2677 if (hr != S_OK) return hr;
2681 pop_indent();
2682 write_element_end(stream, principalW);
2684 pop_indent();
2685 return write_element_end(stream, Principals);
2688 static HRESULT write_settings(IStream *stream, ITaskSettings *settings)
2690 if (!settings)
2691 return write_empty_element(stream, Settings);
2693 FIXME("stub\n");
2694 return S_OK;
2697 static HRESULT write_triggers(IStream *stream, ITriggerCollection *triggers)
2699 if (!triggers)
2700 return write_empty_element(stream, Triggers);
2702 FIXME("stub\n");
2703 return S_OK;
2706 static HRESULT write_actions(IStream *stream, IActionCollection *actions)
2708 if (!actions)
2710 write_element(stream, actionsW);
2711 push_indent();
2712 write_empty_element(stream, Exec);
2713 pop_indent();
2714 return write_element_end(stream, actionsW);
2717 FIXME("stub\n");
2718 return S_OK;
2721 static HRESULT WINAPI TaskDefinition_get_XmlText(ITaskDefinition *iface, BSTR *xml)
2723 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
2724 HRESULT hr;
2725 IStream *stream;
2726 HGLOBAL hmem;
2727 void *p;
2729 TRACE("%p,%p\n", iface, xml);
2731 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16);
2732 if (!hmem) return E_OUTOFMEMORY;
2734 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2735 if (hr != S_OK)
2737 GlobalFree(hmem);
2738 return hr;
2741 hr = write_task_attributes(stream, &taskdef->ITaskDefinition_iface);
2742 if (hr != S_OK) goto failed;
2744 push_indent();
2746 hr = write_registration_info(stream, taskdef->reginfo);
2747 if (hr != S_OK) goto failed;
2749 hr = write_triggers(stream, taskdef->triggers);
2750 if (hr != S_OK) goto failed;
2752 hr = write_principal(stream, taskdef->principal);
2753 if (hr != S_OK) goto failed;
2755 hr = write_settings(stream, taskdef->taskset);
2756 if (hr != S_OK) goto failed;
2758 hr = write_actions(stream, taskdef->actions);
2759 if (hr != S_OK) goto failed;
2761 pop_indent();
2763 write_element_end(stream, Task);
2764 IStream_Write(stream, "\0\0", 2, NULL);
2766 p = GlobalLock(hmem);
2767 *xml = SysAllocString(p);
2768 GlobalUnlock(hmem);
2770 IStream_Release(stream);
2772 return *xml ? S_OK : E_OUTOFMEMORY;
2774 failed:
2775 IStream_Release(stream);
2776 return hr;
2779 static HRESULT read_text_value(IXmlReader *reader, WCHAR **value)
2781 HRESULT hr;
2782 XmlNodeType type;
2784 while (IXmlReader_Read(reader, &type) == S_OK)
2786 switch (type)
2788 case XmlNodeType_Text:
2789 hr = IXmlReader_GetValue(reader, (const WCHAR **)value, NULL);
2790 if (hr != S_OK) return hr;
2791 TRACE("%s\n", debugstr_w(*value));
2792 return S_OK;
2794 case XmlNodeType_Whitespace:
2795 case XmlNodeType_Comment:
2796 break;
2798 default:
2799 FIXME("unexpected node type %d\n", type);
2800 return E_FAIL;
2804 return E_FAIL;
2807 static HRESULT read_variantbool_value(IXmlReader *reader, VARIANT_BOOL *vbool)
2809 static const WCHAR trueW[] = {'t','r','u','e',0};
2810 static const WCHAR falseW[] = {'f','a','l','s','e',0};
2811 HRESULT hr;
2812 WCHAR *value;
2814 hr = read_text_value(reader, &value);
2815 if (hr != S_OK) return hr;
2817 if (!lstrcmpW(value, trueW))
2818 *vbool = VARIANT_TRUE;
2819 else if (!lstrcmpW(value, falseW))
2820 *vbool = VARIANT_FALSE;
2821 else
2823 WARN("unexpected bool value %s\n", debugstr_w(value));
2824 return SCHED_E_INVALIDVALUE;
2827 return S_OK;
2830 static HRESULT read_int_value(IXmlReader *reader, int *int_val)
2832 HRESULT hr;
2833 WCHAR *value;
2835 hr = read_text_value(reader, &value);
2836 if (hr != S_OK) return hr;
2838 *int_val = strtolW(value, NULL, 10);
2840 return S_OK;
2843 static HRESULT read_triggers(IXmlReader *reader, ITaskDefinition *taskdef)
2845 FIXME("stub\n");
2846 return S_OK;
2849 static HRESULT read_principal_attributes(IXmlReader *reader, IPrincipal *principal)
2851 HRESULT hr;
2852 const WCHAR *name;
2853 const WCHAR *value;
2855 hr = IXmlReader_MoveToFirstAttribute(reader);
2857 while (hr == S_OK)
2859 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2860 if (hr != S_OK) break;
2862 hr = IXmlReader_GetValue(reader, &value, NULL);
2863 if (hr != S_OK) break;
2865 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
2867 if (!lstrcmpW(name, id))
2868 IPrincipal_put_Id(principal, (BSTR)value);
2869 else
2870 FIXME("unhandled Principal attribute %s\n", debugstr_w(name));
2872 hr = IXmlReader_MoveToNextAttribute(reader);
2875 return S_OK;
2878 static HRESULT read_principal(IXmlReader *reader, IPrincipal *principal)
2880 HRESULT hr;
2881 XmlNodeType type;
2882 const WCHAR *name;
2883 WCHAR *value;
2885 if (IXmlReader_IsEmptyElement(reader))
2887 TRACE("Principal is empty\n");
2888 return S_OK;
2891 read_principal_attributes(reader, principal);
2893 while (IXmlReader_Read(reader, &type) == S_OK)
2895 switch (type)
2897 case XmlNodeType_EndElement:
2898 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2899 if (hr != S_OK) return hr;
2901 TRACE("/%s\n", debugstr_w(name));
2903 if (!lstrcmpW(name, principalW))
2904 return S_OK;
2906 break;
2908 case XmlNodeType_Element:
2909 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2910 if (hr != S_OK) return hr;
2912 TRACE("Element: %s\n", debugstr_w(name));
2914 if (!lstrcmpW(name, UserId))
2916 hr = read_text_value(reader, &value);
2917 if (hr == S_OK)
2918 IPrincipal_put_UserId(principal, value);
2920 else if (!lstrcmpW(name, LogonType))
2922 hr = read_text_value(reader, &value);
2923 if (hr == S_OK)
2925 TASK_LOGON_TYPE logon = TASK_LOGON_NONE;
2927 if (!lstrcmpW(value, InteractiveToken))
2928 logon = TASK_LOGON_INTERACTIVE_TOKEN;
2929 else
2930 FIXME("unhandled LogonType %s\n", debugstr_w(value));
2932 IPrincipal_put_LogonType(principal, logon);
2935 else if (!lstrcmpW(name, RunLevel))
2937 hr = read_text_value(reader, &value);
2938 if (hr == S_OK)
2940 TASK_RUNLEVEL_TYPE level = TASK_RUNLEVEL_LUA;
2942 if (!lstrcmpW(value, LeastPrivilege))
2943 level = TASK_RUNLEVEL_LUA;
2944 else
2945 FIXME("unhandled RunLevel %s\n", debugstr_w(value));
2947 IPrincipal_put_RunLevel(principal, level);
2950 else
2951 FIXME("unhandled Principal element %s\n", debugstr_w(name));
2953 break;
2955 case XmlNodeType_Whitespace:
2956 case XmlNodeType_Comment:
2957 break;
2959 default:
2960 FIXME("unhandled Principal node type %d\n", type);
2961 break;
2965 WARN("Principal was not terminated\n");
2966 return E_FAIL;
2969 static HRESULT read_principals(IXmlReader *reader, ITaskDefinition *taskdef)
2971 HRESULT hr;
2972 XmlNodeType type;
2973 const WCHAR *name;
2975 if (IXmlReader_IsEmptyElement(reader))
2977 TRACE("Principals is empty\n");
2978 return S_OK;
2981 while (IXmlReader_Read(reader, &type) == S_OK)
2983 switch (type)
2985 case XmlNodeType_EndElement:
2986 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2987 if (hr != S_OK) return hr;
2989 TRACE("/%s\n", debugstr_w(name));
2991 if (!lstrcmpW(name, Principals))
2992 return S_OK;
2994 break;
2996 case XmlNodeType_Element:
2997 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2998 if (hr != S_OK) return hr;
3000 TRACE("Element: %s\n", debugstr_w(name));
3002 if (!lstrcmpW(name, principalW))
3004 IPrincipal *principal;
3006 hr = ITaskDefinition_get_Principal(taskdef, &principal);
3007 if (hr != S_OK) return hr;
3008 hr = read_principal(reader, principal);
3009 IPrincipal_Release(principal);
3011 else
3012 FIXME("unhandled Principals element %s\n", debugstr_w(name));
3014 break;
3016 case XmlNodeType_Whitespace:
3017 case XmlNodeType_Comment:
3018 break;
3020 default:
3021 FIXME("unhandled Principals node type %d\n", type);
3022 break;
3026 WARN("Principals was not terminated\n");
3027 return E_FAIL;
3030 static HRESULT read_actions(IXmlReader *reader, ITaskDefinition *taskdef)
3032 FIXME("stub\n");
3033 return S_OK;
3036 static HRESULT read_idle_settings(IXmlReader *reader, ITaskSettings *taskset)
3038 FIXME("stub\n");
3039 return S_OK;
3042 static HRESULT read_settings(IXmlReader *reader, ITaskSettings *taskset)
3044 HRESULT hr;
3045 XmlNodeType type;
3046 const WCHAR *name;
3047 WCHAR *value;
3048 VARIANT_BOOL bool_val;
3049 int int_val;
3051 if (IXmlReader_IsEmptyElement(reader))
3053 TRACE("Settings is empty\n");
3054 return S_OK;
3057 while (IXmlReader_Read(reader, &type) == S_OK)
3059 switch (type)
3061 case XmlNodeType_EndElement:
3062 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3063 if (hr != S_OK) return hr;
3065 TRACE("/%s\n", debugstr_w(name));
3067 if (!lstrcmpW(name, Settings))
3068 return S_OK;
3070 break;
3072 case XmlNodeType_Element:
3073 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3074 if (hr != S_OK) return hr;
3076 TRACE("Element: %s\n", debugstr_w(name));
3078 if (!lstrcmpW(name, MultipleInstancesPolicy))
3080 hr = read_text_value(reader, &value);
3081 if (hr == S_OK)
3083 int_val = TASK_INSTANCES_IGNORE_NEW;
3085 if (!lstrcmpW(value, IgnoreNew))
3086 int_val = TASK_INSTANCES_IGNORE_NEW;
3087 else
3088 FIXME("unhandled MultipleInstancesPolicy %s\n", debugstr_w(value));
3090 ITaskSettings_put_MultipleInstances(taskset, int_val);
3093 else if (!lstrcmpW(name, DisallowStartIfOnBatteries))
3095 hr = read_variantbool_value(reader, &bool_val);
3096 if (hr != S_OK) return hr;
3097 ITaskSettings_put_DisallowStartIfOnBatteries(taskset, bool_val);
3099 else if (!lstrcmpW(name, AllowStartOnDemand))
3101 hr = read_variantbool_value(reader, &bool_val);
3102 if (hr != S_OK) return hr;
3103 ITaskSettings_put_AllowDemandStart(taskset, bool_val);
3105 else if (!lstrcmpW(name, StopIfGoingOnBatteries))
3107 hr = read_variantbool_value(reader, &bool_val);
3108 if (hr != S_OK) return hr;
3109 ITaskSettings_put_StopIfGoingOnBatteries(taskset, bool_val);
3111 else if (!lstrcmpW(name, AllowHardTerminate))
3113 hr = read_variantbool_value(reader, &bool_val);
3114 if (hr != S_OK) return hr;
3115 ITaskSettings_put_AllowHardTerminate(taskset, bool_val);
3117 else if (!lstrcmpW(name, StartWhenAvailable))
3119 hr = read_variantbool_value(reader, &bool_val);
3120 if (hr != S_OK) return hr;
3121 ITaskSettings_put_StartWhenAvailable(taskset, bool_val);
3123 else if (!lstrcmpW(name, RunOnlyIfNetworkAvailable))
3125 hr = read_variantbool_value(reader, &bool_val);
3126 if (hr != S_OK) return hr;
3127 ITaskSettings_put_RunOnlyIfNetworkAvailable(taskset, bool_val);
3129 else if (!lstrcmpW(name, Enabled))
3131 hr = read_variantbool_value(reader, &bool_val);
3132 if (hr != S_OK) return hr;
3133 ITaskSettings_put_Enabled(taskset, bool_val);
3135 else if (!lstrcmpW(name, Hidden))
3137 hr = read_variantbool_value(reader, &bool_val);
3138 if (hr != S_OK) return hr;
3139 ITaskSettings_put_Hidden(taskset, bool_val);
3141 else if (!lstrcmpW(name, RunOnlyIfIdle))
3143 hr = read_variantbool_value(reader, &bool_val);
3144 if (hr != S_OK) return hr;
3145 ITaskSettings_put_RunOnlyIfIdle(taskset, bool_val);
3147 else if (!lstrcmpW(name, WakeToRun))
3149 hr = read_variantbool_value(reader, &bool_val);
3150 if (hr != S_OK) return hr;
3151 ITaskSettings_put_WakeToRun(taskset, bool_val);
3153 else if (!lstrcmpW(name, ExecutionTimeLimit))
3155 hr = read_text_value(reader, &value);
3156 if (hr == S_OK)
3157 ITaskSettings_put_ExecutionTimeLimit(taskset, value);
3159 else if (!lstrcmpW(name, Priority))
3161 hr = read_int_value(reader, &int_val);
3162 if (hr == S_OK)
3163 ITaskSettings_put_Priority(taskset, int_val);
3165 else if (!lstrcmpW(name, IdleSettings))
3167 hr = read_idle_settings(reader, taskset);
3168 if (hr != S_OK) return hr;
3170 else
3171 FIXME("unhandled Settings element %s\n", debugstr_w(name));
3173 break;
3175 case XmlNodeType_Whitespace:
3176 case XmlNodeType_Comment:
3177 break;
3179 default:
3180 FIXME("unhandled Settings node type %d\n", type);
3181 break;
3185 WARN("Settings was not terminated\n");
3186 return SCHED_E_MALFORMEDXML;
3189 static HRESULT read_registration_info(IXmlReader *reader, IRegistrationInfo *info)
3191 HRESULT hr;
3192 XmlNodeType type;
3193 const WCHAR *name;
3194 WCHAR *value;
3196 if (IXmlReader_IsEmptyElement(reader))
3198 TRACE("RegistrationInfo is empty\n");
3199 return S_OK;
3202 while (IXmlReader_Read(reader, &type) == S_OK)
3204 switch (type)
3206 case XmlNodeType_EndElement:
3207 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3208 if (hr != S_OK) return hr;
3210 TRACE("/%s\n", debugstr_w(name));
3212 if (!lstrcmpW(name, RegistrationInfo))
3213 return S_OK;
3215 break;
3217 case XmlNodeType_Element:
3218 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3219 if (hr != S_OK) return hr;
3221 TRACE("Element: %s\n", debugstr_w(name));
3223 if (!lstrcmpW(name, Author))
3225 hr = read_text_value(reader, &value);
3226 if (hr == S_OK)
3227 IRegistrationInfo_put_Author(info, value);
3229 else if (!lstrcmpW(name, Description))
3231 hr = read_text_value(reader, &value);
3232 if (hr == S_OK)
3233 IRegistrationInfo_put_Description(info, value);
3235 else
3236 FIXME("unhandled RegistrationInfo element %s\n", debugstr_w(name));
3238 break;
3240 case XmlNodeType_Whitespace:
3241 case XmlNodeType_Comment:
3242 break;
3244 default:
3245 FIXME("unhandled RegistrationInfo node type %d\n", type);
3246 break;
3250 WARN("RegistrationInfo was not terminated\n");
3251 return SCHED_E_MALFORMEDXML;
3254 static HRESULT read_task_attributes(IXmlReader *reader, ITaskDefinition *taskdef)
3256 HRESULT hr;
3257 ITaskSettings *taskset;
3258 const WCHAR *name;
3259 const WCHAR *value;
3260 BOOL xmlns_ok = FALSE;
3262 TRACE("\n");
3264 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3265 if (hr != S_OK) return hr;
3267 hr = IXmlReader_MoveToFirstAttribute(reader);
3269 while (hr == S_OK)
3271 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3272 if (hr != S_OK) break;
3274 hr = IXmlReader_GetValue(reader, &value, NULL);
3275 if (hr != S_OK) break;
3277 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
3279 if (!lstrcmpW(name, version))
3281 TASK_COMPATIBILITY compatibility = TASK_COMPATIBILITY_V2;
3283 if (!lstrcmpW(value, v1_0))
3284 compatibility = TASK_COMPATIBILITY_AT;
3285 else if (!lstrcmpW(value, v1_1))
3286 compatibility = TASK_COMPATIBILITY_V1;
3287 else if (!lstrcmpW(value, v1_2))
3288 compatibility = TASK_COMPATIBILITY_V2;
3289 else if (!lstrcmpW(value, v1_3))
3290 compatibility = TASK_COMPATIBILITY_V2_1;
3291 else
3292 FIXME("unknown version %s\n", debugstr_w(value));
3294 ITaskSettings_put_Compatibility(taskset, compatibility);
3296 else if (!lstrcmpW(name, xmlns))
3298 if (lstrcmpW(value, task_ns))
3300 FIXME("unknown namespace %s\n", debugstr_w(value));
3301 break;
3303 xmlns_ok = TRUE;
3305 else
3306 FIXME("unhandled Task attribute %s\n", debugstr_w(name));
3308 hr = IXmlReader_MoveToNextAttribute(reader);
3311 ITaskSettings_Release(taskset);
3312 return xmlns_ok ? S_OK : SCHED_E_NAMESPACE;
3315 static HRESULT read_task(IXmlReader *reader, ITaskDefinition *taskdef)
3317 HRESULT hr;
3318 XmlNodeType type;
3319 const WCHAR *name;
3321 if (IXmlReader_IsEmptyElement(reader))
3323 TRACE("Task is empty\n");
3324 return S_OK;
3327 while (IXmlReader_Read(reader, &type) == S_OK)
3329 switch (type)
3331 case XmlNodeType_EndElement:
3332 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3333 if (hr != S_OK) return hr;
3335 TRACE("/%s\n", debugstr_w(name));
3337 if (!lstrcmpW(name, Task))
3338 return S_OK;
3340 break;
3342 case XmlNodeType_Element:
3343 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3344 if (hr != S_OK) return hr;
3346 TRACE("Element: %s\n", debugstr_w(name));
3348 if (!lstrcmpW(name, RegistrationInfo))
3350 IRegistrationInfo *info;
3352 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &info);
3353 if (hr != S_OK) return hr;
3354 hr = read_registration_info(reader, info);
3355 IRegistrationInfo_Release(info);
3357 else if (!lstrcmpW(name, Settings))
3359 ITaskSettings *taskset;
3361 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
3362 if (hr != S_OK) return hr;
3363 hr = read_settings(reader, taskset);
3364 ITaskSettings_Release(taskset);
3366 else if (!lstrcmpW(name, Triggers))
3367 hr = read_triggers(reader, taskdef);
3368 else if (!lstrcmpW(name, Principals))
3369 hr = read_principals(reader, taskdef);
3370 else if (!lstrcmpW(name, actionsW))
3371 hr = read_actions(reader, taskdef);
3372 else
3373 FIXME("unhandled Task element %s\n", debugstr_w(name));
3375 if (hr != S_OK) return hr;
3376 break;
3378 case XmlNodeType_Comment:
3379 case XmlNodeType_Whitespace:
3380 break;
3382 default:
3383 FIXME("unhandled Task node type %d\n", type);
3384 break;
3388 WARN("Task was not terminated\n");
3389 return SCHED_E_MALFORMEDXML;
3392 static HRESULT read_xml(IXmlReader *reader, ITaskDefinition *taskdef)
3394 HRESULT hr;
3395 XmlNodeType type;
3396 const WCHAR *name;
3398 while (IXmlReader_Read(reader, &type) == S_OK)
3400 switch (type)
3402 case XmlNodeType_XmlDeclaration:
3403 TRACE("XmlDeclaration\n");
3404 break;
3406 case XmlNodeType_Element:
3407 hr = IXmlReader_GetLocalName(reader, &name, NULL);
3408 if (hr != S_OK) return hr;
3410 TRACE("Element: %s\n", debugstr_w(name));
3412 if (!lstrcmpW(name, Task))
3414 hr = read_task_attributes(reader, taskdef);
3415 if (hr != S_OK) return hr;
3417 return read_task(reader, taskdef);
3419 else
3420 FIXME("unhandled XML element %s\n", debugstr_w(name));
3422 break;
3424 case XmlNodeType_Comment:
3425 case XmlNodeType_Whitespace:
3426 break;
3428 default:
3429 FIXME("unhandled XML node type %d\n", type);
3430 break;
3434 WARN("Task definition was not found\n");
3435 return SCHED_E_MALFORMEDXML;
3438 static HRESULT WINAPI TaskDefinition_put_XmlText(ITaskDefinition *iface, BSTR xml)
3440 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
3441 HRESULT hr;
3442 IStream *stream;
3443 IXmlReader *reader;
3444 HGLOBAL hmem;
3445 void *buf;
3447 TRACE("%p,%s\n", iface, debugstr_w(xml));
3449 if (!xml) return E_INVALIDARG;
3451 hmem = GlobalAlloc(0, lstrlenW(xml) * sizeof(WCHAR));
3452 if (!hmem) return E_OUTOFMEMORY;
3454 buf = GlobalLock(hmem);
3455 memcpy(buf, xml, lstrlenW(xml) * sizeof(WCHAR));
3456 GlobalUnlock(hmem);
3458 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
3459 if (hr != S_OK)
3461 GlobalFree(hmem);
3462 return hr;
3465 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
3466 if (hr != S_OK)
3468 IStream_Release(stream);
3469 return hr;
3472 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
3473 if (hr == S_OK)
3475 if (taskdef->reginfo)
3477 IRegistrationInfo_Release(taskdef->reginfo);
3478 taskdef->reginfo = NULL;
3480 if (taskdef->taskset)
3482 ITaskSettings_Release(taskdef->taskset);
3483 taskdef->taskset = NULL;
3485 if (taskdef->triggers)
3487 ITriggerCollection_Release(taskdef->triggers);
3488 taskdef->triggers = NULL;
3490 if (taskdef->principal)
3492 IPrincipal_Release(taskdef->principal);
3493 taskdef->principal = NULL;
3495 if (taskdef->actions)
3497 IActionCollection_Release(taskdef->actions);
3498 taskdef->actions = NULL;
3501 hr = read_xml(reader, iface);
3504 IXmlReader_Release(reader);
3505 IStream_Release(stream);
3507 return hr;
3510 static const ITaskDefinitionVtbl TaskDefinition_vtbl =
3512 TaskDefinition_QueryInterface,
3513 TaskDefinition_AddRef,
3514 TaskDefinition_Release,
3515 TaskDefinition_GetTypeInfoCount,
3516 TaskDefinition_GetTypeInfo,
3517 TaskDefinition_GetIDsOfNames,
3518 TaskDefinition_Invoke,
3519 TaskDefinition_get_RegistrationInfo,
3520 TaskDefinition_put_RegistrationInfo,
3521 TaskDefinition_get_Triggers,
3522 TaskDefinition_put_Triggers,
3523 TaskDefinition_get_Settings,
3524 TaskDefinition_put_Settings,
3525 TaskDefinition_get_Data,
3526 TaskDefinition_put_Data,
3527 TaskDefinition_get_Principal,
3528 TaskDefinition_put_Principal,
3529 TaskDefinition_get_Actions,
3530 TaskDefinition_put_Actions,
3531 TaskDefinition_get_XmlText,
3532 TaskDefinition_put_XmlText
3535 HRESULT TaskDefinition_create(ITaskDefinition **obj)
3537 TaskDefinition *taskdef;
3539 taskdef = heap_alloc_zero(sizeof(*taskdef));
3540 if (!taskdef) return E_OUTOFMEMORY;
3542 taskdef->ITaskDefinition_iface.lpVtbl = &TaskDefinition_vtbl;
3543 taskdef->ref = 1;
3544 *obj = &taskdef->ITaskDefinition_iface;
3546 TRACE("created %p\n", *obj);
3548 return S_OK;
3551 typedef struct
3553 ITaskService ITaskService_iface;
3554 LONG ref;
3555 BOOL connected;
3556 DWORD version;
3557 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3558 } TaskService;
3560 static inline TaskService *impl_from_ITaskService(ITaskService *iface)
3562 return CONTAINING_RECORD(iface, TaskService, ITaskService_iface);
3565 static ULONG WINAPI TaskService_AddRef(ITaskService *iface)
3567 TaskService *task_svc = impl_from_ITaskService(iface);
3568 return InterlockedIncrement(&task_svc->ref);
3571 static ULONG WINAPI TaskService_Release(ITaskService *iface)
3573 TaskService *task_svc = impl_from_ITaskService(iface);
3574 LONG ref = InterlockedDecrement(&task_svc->ref);
3576 if (!ref)
3578 TRACE("destroying %p\n", iface);
3579 heap_free(task_svc);
3582 return ref;
3585 static HRESULT WINAPI TaskService_QueryInterface(ITaskService *iface, REFIID riid, void **obj)
3587 if (!riid || !obj) return E_INVALIDARG;
3589 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
3591 if (IsEqualGUID(riid, &IID_ITaskService) ||
3592 IsEqualGUID(riid, &IID_IDispatch) ||
3593 IsEqualGUID(riid, &IID_IUnknown))
3595 ITaskService_AddRef(iface);
3596 *obj = iface;
3597 return S_OK;
3600 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
3601 *obj = NULL;
3602 return E_NOINTERFACE;
3605 static HRESULT WINAPI TaskService_GetTypeInfoCount(ITaskService *iface, UINT *count)
3607 FIXME("%p,%p: stub\n", iface, count);
3608 return E_NOTIMPL;
3611 static HRESULT WINAPI TaskService_GetTypeInfo(ITaskService *iface, UINT index, LCID lcid, ITypeInfo **info)
3613 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
3614 return E_NOTIMPL;
3617 static HRESULT WINAPI TaskService_GetIDsOfNames(ITaskService *iface, REFIID riid, LPOLESTR *names,
3618 UINT count, LCID lcid, DISPID *dispid)
3620 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
3621 return E_NOTIMPL;
3624 static HRESULT WINAPI TaskService_Invoke(ITaskService *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
3625 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
3627 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
3628 params, result, excepinfo, argerr);
3629 return E_NOTIMPL;
3632 static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITaskFolder **folder)
3634 TaskService *task_svc = impl_from_ITaskService(iface);
3636 TRACE("%p,%s,%p\n", iface, debugstr_w(path), folder);
3638 if (!folder) return E_POINTER;
3640 if (!task_svc->connected)
3641 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3643 return TaskFolder_create(path, NULL, folder, FALSE);
3646 static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks)
3648 FIXME("%p,%x,%p: stub\n", iface, flags, tasks);
3649 return E_NOTIMPL;
3652 static HRESULT WINAPI TaskService_NewTask(ITaskService *iface, DWORD flags, ITaskDefinition **definition)
3654 TRACE("%p,%x,%p\n", iface, flags, definition);
3656 if (!definition) return E_POINTER;
3658 if (flags)
3659 FIXME("unsupported flags %x\n", flags);
3661 return TaskDefinition_create(definition);
3664 static inline BOOL is_variant_null(const VARIANT *var)
3666 return V_VT(var) == VT_EMPTY || V_VT(var) == VT_NULL ||
3667 (V_VT(var) == VT_BSTR && (V_BSTR(var) == NULL || !*V_BSTR(var)));
3670 static HRESULT start_schedsvc(void)
3672 static const WCHAR scheduleW[] = { 'S','c','h','e','d','u','l','e',0 };
3673 SC_HANDLE scm, service;
3674 SERVICE_STATUS_PROCESS status;
3675 ULONGLONG start_time;
3676 HRESULT hr = SCHED_E_SERVICE_NOT_RUNNING;
3678 TRACE("Trying to start %s service\n", debugstr_w(scheduleW));
3680 scm = OpenSCManagerW(NULL, NULL, 0);
3681 if (!scm) return SCHED_E_SERVICE_NOT_INSTALLED;
3683 service = OpenServiceW(scm, scheduleW, SERVICE_START | SERVICE_QUERY_STATUS);
3684 if (service)
3686 if (StartServiceW(service, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
3688 start_time = GetTickCount64();
3691 DWORD dummy;
3693 if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(status), &dummy))
3695 WARN("failed to query scheduler status (%u)\n", GetLastError());
3696 break;
3699 if (status.dwCurrentState == SERVICE_RUNNING)
3701 hr = S_OK;
3702 break;
3705 if (GetTickCount64() - start_time > 30000) break;
3706 Sleep(1000);
3708 } while (status.dwCurrentState == SERVICE_START_PENDING);
3710 if (status.dwCurrentState != SERVICE_RUNNING)
3711 WARN("scheduler failed to start %u\n", status.dwCurrentState);
3713 else
3714 WARN("failed to start scheduler service (%u)\n", GetLastError());
3716 CloseServiceHandle(service);
3718 else
3719 WARN("failed to open scheduler service (%u)\n", GetLastError());
3721 CloseServiceHandle(scm);
3722 return hr;
3725 static HRESULT WINAPI TaskService_Connect(ITaskService *iface, VARIANT server, VARIANT user, VARIANT domain, VARIANT password)
3727 static WCHAR ncalrpc[] = { 'n','c','a','l','r','p','c',0 };
3728 TaskService *task_svc = impl_from_ITaskService(iface);
3729 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
3730 DWORD len;
3731 HRESULT hr;
3732 RPC_WSTR binding_str;
3733 extern handle_t rpc_handle;
3735 TRACE("%p,%s,%s,%s,%s\n", iface, debugstr_variant(&server), debugstr_variant(&user),
3736 debugstr_variant(&domain), debugstr_variant(&password));
3738 if (!is_variant_null(&user) || !is_variant_null(&domain) || !is_variant_null(&password))
3739 FIXME("user/domain/password are ignored\n");
3741 len = sizeof(comp_name)/sizeof(comp_name[0]);
3742 if (!GetComputerNameW(comp_name, &len))
3743 return HRESULT_FROM_WIN32(GetLastError());
3745 if (!is_variant_null(&server))
3747 const WCHAR *server_name;
3749 if (V_VT(&server) != VT_BSTR)
3751 FIXME("server variant type %d is not supported\n", V_VT(&server));
3752 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3755 /* skip UNC prefix if any */
3756 server_name = V_BSTR(&server);
3757 if (server_name[0] == '\\' && server_name[1] == '\\')
3758 server_name += 2;
3760 if (strcmpiW(server_name, comp_name))
3762 FIXME("connection to remote server %s is not supported\n", debugstr_w(V_BSTR(&server)));
3763 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
3767 hr = start_schedsvc();
3768 if (hr != S_OK) return hr;
3770 hr = RpcStringBindingComposeW(NULL, ncalrpc, NULL, NULL, NULL, &binding_str);
3771 if (hr != RPC_S_OK) return hr;
3772 hr = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
3773 RpcStringFreeW(&binding_str);
3774 if (hr != RPC_S_OK) return hr;
3776 /* Make sure that the connection works */
3777 hr = SchRpcHighestVersion(&task_svc->version);
3778 if (hr != S_OK) return hr;
3780 TRACE("server version %#x\n", task_svc->version);
3782 strcpyW(task_svc->comp_name, comp_name);
3783 task_svc->connected = TRUE;
3785 return S_OK;
3788 static HRESULT WINAPI TaskService_get_Connected(ITaskService *iface, VARIANT_BOOL *connected)
3790 TaskService *task_svc = impl_from_ITaskService(iface);
3792 TRACE("%p,%p\n", iface, connected);
3794 if (!connected) return E_POINTER;
3796 *connected = task_svc->connected ? VARIANT_TRUE : VARIANT_FALSE;
3798 return S_OK;
3801 static HRESULT WINAPI TaskService_get_TargetServer(ITaskService *iface, BSTR *server)
3803 TaskService *task_svc = impl_from_ITaskService(iface);
3805 TRACE("%p,%p\n", iface, server);
3807 if (!server) return E_POINTER;
3809 if (!task_svc->connected)
3810 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3812 *server = SysAllocString(task_svc->comp_name);
3813 if (!*server) return E_OUTOFMEMORY;
3815 return S_OK;
3818 static HRESULT WINAPI TaskService_get_ConnectedUser(ITaskService *iface, BSTR *user)
3820 FIXME("%p,%p: stub\n", iface, user);
3821 return E_NOTIMPL;
3824 static HRESULT WINAPI TaskService_get_ConnectedDomain(ITaskService *iface, BSTR *domain)
3826 FIXME("%p,%p: stub\n", iface, domain);
3827 return E_NOTIMPL;
3830 static HRESULT WINAPI TaskService_get_HighestVersion(ITaskService *iface, DWORD *version)
3832 TaskService *task_svc = impl_from_ITaskService(iface);
3834 TRACE("%p,%p\n", iface, version);
3836 if (!version) return E_POINTER;
3838 if (!task_svc->connected)
3839 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
3841 *version = task_svc->version;
3843 return S_OK;
3846 static const ITaskServiceVtbl TaskService_vtbl =
3848 TaskService_QueryInterface,
3849 TaskService_AddRef,
3850 TaskService_Release,
3851 TaskService_GetTypeInfoCount,
3852 TaskService_GetTypeInfo,
3853 TaskService_GetIDsOfNames,
3854 TaskService_Invoke,
3855 TaskService_GetFolder,
3856 TaskService_GetRunningTasks,
3857 TaskService_NewTask,
3858 TaskService_Connect,
3859 TaskService_get_Connected,
3860 TaskService_get_TargetServer,
3861 TaskService_get_ConnectedUser,
3862 TaskService_get_ConnectedDomain,
3863 TaskService_get_HighestVersion
3866 HRESULT TaskService_create(void **obj)
3868 TaskService *task_svc;
3870 task_svc = heap_alloc(sizeof(*task_svc));
3871 if (!task_svc) return E_OUTOFMEMORY;
3873 task_svc->ITaskService_iface.lpVtbl = &TaskService_vtbl;
3874 task_svc->ref = 1;
3875 task_svc->connected = FALSE;
3876 *obj = &task_svc->ITaskService_iface;
3878 TRACE("created %p\n", *obj);
3880 return S_OK;
3883 void __RPC_FAR *__RPC_USER MIDL_user_allocate(SIZE_T n)
3885 return HeapAlloc(GetProcessHeap(), 0, n);
3888 void __RPC_USER MIDL_user_free(void __RPC_FAR *p)
3890 HeapFree(GetProcessHeap(), 0, p);