taskschd: Add a check for the task namespace.
[wine.git] / dlls / taskschd / task.c
blob1288314bb2f509bcf7ef70d6e3d3f4e0e009e63e
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 "taskschd_private.h"
31 #include "wine/unicode.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(taskschd);
36 typedef struct
38 IRegistrationInfo IRegistrationInfo_iface;
39 LONG ref;
40 } registration_info;
42 static inline registration_info *impl_from_IRegistrationInfo(IRegistrationInfo *iface)
44 return CONTAINING_RECORD(iface, registration_info, IRegistrationInfo_iface);
47 static ULONG WINAPI RegistrationInfo_AddRef(IRegistrationInfo *iface)
49 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
50 return InterlockedIncrement(&reginfo->ref);
53 static ULONG WINAPI RegistrationInfo_Release(IRegistrationInfo *iface)
55 registration_info *reginfo = impl_from_IRegistrationInfo(iface);
56 LONG ref = InterlockedDecrement(&reginfo->ref);
58 if (!ref)
60 TRACE("destroying %p\n", iface);
61 heap_free(reginfo);
64 return ref;
67 static HRESULT WINAPI RegistrationInfo_QueryInterface(IRegistrationInfo *iface, REFIID riid, void **obj)
69 if (!riid || !obj) return E_INVALIDARG;
71 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
73 if (IsEqualGUID(riid, &IID_IRegistrationInfo) ||
74 IsEqualGUID(riid, &IID_IDispatch) ||
75 IsEqualGUID(riid, &IID_IUnknown))
77 IRegistrationInfo_AddRef(iface);
78 *obj = iface;
79 return S_OK;
82 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
83 *obj = NULL;
84 return E_NOINTERFACE;
87 static HRESULT WINAPI RegistrationInfo_GetTypeInfoCount(IRegistrationInfo *iface, UINT *count)
89 FIXME("%p,%p: stub\n", iface, count);
90 return E_NOTIMPL;
93 static HRESULT WINAPI RegistrationInfo_GetTypeInfo(IRegistrationInfo *iface, UINT index, LCID lcid, ITypeInfo **info)
95 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
96 return E_NOTIMPL;
99 static HRESULT WINAPI RegistrationInfo_GetIDsOfNames(IRegistrationInfo *iface, REFIID riid, LPOLESTR *names,
100 UINT count, LCID lcid, DISPID *dispid)
102 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
103 return E_NOTIMPL;
106 static HRESULT WINAPI RegistrationInfo_Invoke(IRegistrationInfo *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
107 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
109 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
110 params, result, excepinfo, argerr);
111 return E_NOTIMPL;
114 static HRESULT WINAPI RegistrationInfo_get_Description(IRegistrationInfo *iface, BSTR *description)
116 FIXME("%p,%p: stub\n", iface, description);
117 return E_NOTIMPL;
120 static HRESULT WINAPI RegistrationInfo_put_Description(IRegistrationInfo *iface, BSTR description)
122 FIXME("%p,%p: stub\n", iface, debugstr_w(description));
123 return E_NOTIMPL;
126 static HRESULT WINAPI RegistrationInfo_get_Author(IRegistrationInfo *iface, BSTR *author)
128 FIXME("%p,%p: stub\n", iface, author);
129 return E_NOTIMPL;
132 static HRESULT WINAPI RegistrationInfo_put_Author(IRegistrationInfo *iface, BSTR author)
134 FIXME("%p,%p: stub\n", iface, debugstr_w(author));
135 return E_NOTIMPL;
138 static HRESULT WINAPI RegistrationInfo_get_Version(IRegistrationInfo *iface, BSTR *version)
140 FIXME("%p,%p: stub\n", iface, version);
141 return E_NOTIMPL;
144 static HRESULT WINAPI RegistrationInfo_put_Version(IRegistrationInfo *iface, BSTR version)
146 FIXME("%p,%p: stub\n", iface, debugstr_w(version));
147 return E_NOTIMPL;
150 static HRESULT WINAPI RegistrationInfo_get_Date(IRegistrationInfo *iface, BSTR *date)
152 FIXME("%p,%p: stub\n", iface, date);
153 return E_NOTIMPL;
156 static HRESULT WINAPI RegistrationInfo_put_Date(IRegistrationInfo *iface, BSTR date)
158 FIXME("%p,%p: stub\n", iface, debugstr_w(date));
159 return E_NOTIMPL;
162 static HRESULT WINAPI RegistrationInfo_get_Documentation(IRegistrationInfo *iface, BSTR *doc)
164 FIXME("%p,%p: stub\n", iface, doc);
165 return E_NOTIMPL;
168 static HRESULT WINAPI RegistrationInfo_put_Documentation(IRegistrationInfo *iface, BSTR doc)
170 FIXME("%p,%p: stub\n", iface, debugstr_w(doc));
171 return E_NOTIMPL;
174 static HRESULT WINAPI RegistrationInfo_get_XmlText(IRegistrationInfo *iface, BSTR *xml)
176 FIXME("%p,%p: stub\n", iface, xml);
177 return E_NOTIMPL;
180 static HRESULT WINAPI RegistrationInfo_put_XmlText(IRegistrationInfo *iface, BSTR xml)
182 FIXME("%p,%p: stub\n", iface, debugstr_w(xml));
183 return E_NOTIMPL;
186 static HRESULT WINAPI RegistrationInfo_get_URI(IRegistrationInfo *iface, BSTR *uri)
188 FIXME("%p,%p: stub\n", iface, uri);
189 return E_NOTIMPL;
192 static HRESULT WINAPI RegistrationInfo_put_URI(IRegistrationInfo *iface, BSTR uri)
194 FIXME("%p,%p: stub\n", iface, debugstr_w(uri));
195 return E_NOTIMPL;
198 static HRESULT WINAPI RegistrationInfo_get_SecurityDescriptor(IRegistrationInfo *iface, VARIANT *sddl)
200 FIXME("%p,%p: stub\n", iface, sddl);
201 return E_NOTIMPL;
204 static HRESULT WINAPI RegistrationInfo_put_SecurityDescriptor(IRegistrationInfo *iface, VARIANT sddl)
206 FIXME("%p,%p: stub\n", iface, debugstr_variant(&sddl));
207 return E_NOTIMPL;
210 static HRESULT WINAPI RegistrationInfo_get_Source(IRegistrationInfo *iface, BSTR *source)
212 FIXME("%p,%p: stub\n", iface, source);
213 return E_NOTIMPL;
216 static HRESULT WINAPI RegistrationInfo_put_Source(IRegistrationInfo *iface, BSTR source)
218 FIXME("%p,%p: stub\n", iface, debugstr_w(source));
219 return E_NOTIMPL;
222 static const IRegistrationInfoVtbl RegistrationInfo_vtbl =
224 RegistrationInfo_QueryInterface,
225 RegistrationInfo_AddRef,
226 RegistrationInfo_Release,
227 RegistrationInfo_GetTypeInfoCount,
228 RegistrationInfo_GetTypeInfo,
229 RegistrationInfo_GetIDsOfNames,
230 RegistrationInfo_Invoke,
231 RegistrationInfo_get_Description,
232 RegistrationInfo_put_Description,
233 RegistrationInfo_get_Author,
234 RegistrationInfo_put_Author,
235 RegistrationInfo_get_Version,
236 RegistrationInfo_put_Version,
237 RegistrationInfo_get_Date,
238 RegistrationInfo_put_Date,
239 RegistrationInfo_get_Documentation,
240 RegistrationInfo_put_Documentation,
241 RegistrationInfo_get_XmlText,
242 RegistrationInfo_put_XmlText,
243 RegistrationInfo_get_URI,
244 RegistrationInfo_put_URI,
245 RegistrationInfo_get_SecurityDescriptor,
246 RegistrationInfo_put_SecurityDescriptor,
247 RegistrationInfo_get_Source,
248 RegistrationInfo_put_Source
251 static HRESULT RegistrationInfo_create(IRegistrationInfo **obj)
253 registration_info *reginfo;
255 reginfo = heap_alloc_zero(sizeof(*reginfo));
256 if (!reginfo) return E_OUTOFMEMORY;
258 reginfo->IRegistrationInfo_iface.lpVtbl = &RegistrationInfo_vtbl;
259 reginfo->ref = 1;
260 *obj = &reginfo->IRegistrationInfo_iface;
262 TRACE("created %p\n", *obj);
264 return S_OK;
267 typedef struct
269 ITaskSettings ITaskSettings_iface;
270 LONG ref;
271 WCHAR *restart_interval;
272 WCHAR *execution_time_limit;
273 WCHAR *delete_expired_task_after;
274 int restart_count;
275 int priority;
276 TASK_INSTANCES_POLICY policy;
277 TASK_COMPATIBILITY compatibility;
278 BOOL allow_on_demand_start;
279 BOOL stop_if_going_on_batteries;
280 BOOL disallow_start_if_on_batteries;
281 BOOL allow_hard_terminate;
282 BOOL start_when_available;
283 BOOL run_only_if_network_available;
284 BOOL enabled;
285 BOOL hidden;
286 BOOL run_only_if_idle;
287 BOOL wake_to_run;
288 } TaskSettings;
290 static inline TaskSettings *impl_from_ITaskSettings(ITaskSettings *iface)
292 return CONTAINING_RECORD(iface, TaskSettings, ITaskSettings_iface);
295 static ULONG WINAPI TaskSettings_AddRef(ITaskSettings *iface)
297 TaskSettings *taskset = impl_from_ITaskSettings(iface);
298 return InterlockedIncrement(&taskset->ref);
301 static ULONG WINAPI TaskSettings_Release(ITaskSettings *iface)
303 TaskSettings *taskset = impl_from_ITaskSettings(iface);
304 LONG ref = InterlockedDecrement(&taskset->ref);
306 if (!ref)
308 TRACE("destroying %p\n", iface);
309 heap_free(taskset->restart_interval);
310 heap_free(taskset->execution_time_limit);
311 heap_free(taskset->delete_expired_task_after);
312 heap_free(taskset);
315 return ref;
318 static HRESULT WINAPI TaskSettings_QueryInterface(ITaskSettings *iface, REFIID riid, void **obj)
320 if (!riid || !obj) return E_INVALIDARG;
322 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
324 if (IsEqualGUID(riid, &IID_ITaskSettings) ||
325 IsEqualGUID(riid, &IID_IDispatch) ||
326 IsEqualGUID(riid, &IID_IUnknown))
328 ITaskSettings_AddRef(iface);
329 *obj = iface;
330 return S_OK;
333 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
334 *obj = NULL;
335 return E_NOINTERFACE;
338 static HRESULT WINAPI TaskSettings_GetTypeInfoCount(ITaskSettings *iface, UINT *count)
340 FIXME("%p,%p: stub\n", iface, count);
341 return E_NOTIMPL;
344 static HRESULT WINAPI TaskSettings_GetTypeInfo(ITaskSettings *iface, UINT index, LCID lcid, ITypeInfo **info)
346 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
347 return E_NOTIMPL;
350 static HRESULT WINAPI TaskSettings_GetIDsOfNames(ITaskSettings *iface, REFIID riid, LPOLESTR *names,
351 UINT count, LCID lcid, DISPID *dispid)
353 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
354 return E_NOTIMPL;
357 static HRESULT WINAPI TaskSettings_Invoke(ITaskSettings *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
358 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
360 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
361 params, result, excepinfo, argerr);
362 return E_NOTIMPL;
365 static HRESULT WINAPI TaskSettings_get_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL *allow)
367 TaskSettings *taskset = impl_from_ITaskSettings(iface);
369 TRACE("%p,%p\n", iface, allow);
371 if (!allow) return E_POINTER;
373 *allow = taskset->allow_on_demand_start ? VARIANT_TRUE : VARIANT_FALSE;
375 return S_OK;
378 static HRESULT WINAPI TaskSettings_put_AllowDemandStart(ITaskSettings *iface, VARIANT_BOOL allow)
380 FIXME("%p,%d: stub\n", iface, allow);
381 return E_NOTIMPL;
384 static HRESULT WINAPI TaskSettings_get_RestartInterval(ITaskSettings *iface, BSTR *interval)
386 TaskSettings *taskset = impl_from_ITaskSettings(iface);
388 TRACE("%p,%p\n", iface, interval);
390 if (!interval) return E_POINTER;
392 if (!taskset->restart_interval)
394 *interval = NULL;
395 return S_OK;
398 *interval = SysAllocString(taskset->restart_interval);
399 if (!*interval) return E_OUTOFMEMORY;
401 return S_OK;
404 static HRESULT WINAPI TaskSettings_put_RestartInterval(ITaskSettings *iface, BSTR interval)
406 TRACE("%p,%s\n", iface, debugstr_w(interval));
407 return E_NOTIMPL;
410 static HRESULT WINAPI TaskSettings_get_RestartCount(ITaskSettings *iface, INT *count)
412 TaskSettings *taskset = impl_from_ITaskSettings(iface);
414 TRACE("%p,%p\n", iface, count);
416 if (!count) return E_POINTER;
418 *count = taskset->restart_count;
420 return S_OK;
423 static HRESULT WINAPI TaskSettings_put_RestartCount(ITaskSettings *iface, INT count)
425 FIXME("%p,%d: stub\n", iface, count);
426 return E_NOTIMPL;
429 static HRESULT WINAPI TaskSettings_get_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY *policy)
431 TaskSettings *taskset = impl_from_ITaskSettings(iface);
433 TRACE("%p,%p\n", iface, policy);
435 if (!policy) return E_POINTER;
437 *policy = taskset->policy;
439 return S_OK;
442 static HRESULT WINAPI TaskSettings_put_MultipleInstances(ITaskSettings *iface, TASK_INSTANCES_POLICY policy)
444 FIXME("%p,%d: stub\n", iface, policy);
445 return E_NOTIMPL;
448 static HRESULT WINAPI TaskSettings_get_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL *stop)
450 TaskSettings *taskset = impl_from_ITaskSettings(iface);
452 TRACE("%p,%p\n", iface, stop);
454 if (!stop) return E_POINTER;
456 *stop = taskset->stop_if_going_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
458 return S_OK;
461 static HRESULT WINAPI TaskSettings_put_StopIfGoingOnBatteries(ITaskSettings *iface, VARIANT_BOOL stop)
463 FIXME("%p,%d: stub\n", iface, stop);
464 return E_NOTIMPL;
467 static HRESULT WINAPI TaskSettings_get_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL *disallow)
469 TaskSettings *taskset = impl_from_ITaskSettings(iface);
471 TRACE("%p,%p\n", iface, disallow);
473 if (!disallow) return E_POINTER;
475 *disallow = taskset->disallow_start_if_on_batteries ? VARIANT_TRUE : VARIANT_FALSE;
477 return S_OK;
480 static HRESULT WINAPI TaskSettings_put_DisallowStartIfOnBatteries(ITaskSettings *iface, VARIANT_BOOL disallow)
482 FIXME("%p,%d: stub\n", iface, disallow);
483 return E_NOTIMPL;
486 static HRESULT WINAPI TaskSettings_get_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL *allow)
488 TaskSettings *taskset = impl_from_ITaskSettings(iface);
490 TRACE("%p,%p\n", iface, allow);
492 if (!allow) return E_POINTER;
494 *allow = taskset->allow_hard_terminate ? VARIANT_TRUE : VARIANT_FALSE;
496 return S_OK;
499 static HRESULT WINAPI TaskSettings_put_AllowHardTerminate(ITaskSettings *iface, VARIANT_BOOL allow)
501 FIXME("%p,%d: stub\n", iface, allow);
502 return E_NOTIMPL;
505 static HRESULT WINAPI TaskSettings_get_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL *start)
507 TaskSettings *taskset = impl_from_ITaskSettings(iface);
509 TRACE("%p,%p\n", iface, start);
511 if (!start) return E_POINTER;
513 *start = taskset->start_when_available ? VARIANT_TRUE : VARIANT_FALSE;
515 return S_OK;
518 static HRESULT WINAPI TaskSettings_put_StartWhenAvailable(ITaskSettings *iface, VARIANT_BOOL start)
520 FIXME("%p,%d: stub\n", iface, start);
521 return E_NOTIMPL;
524 static HRESULT WINAPI TaskSettings_get_XmlText(ITaskSettings *iface, BSTR *xml)
526 FIXME("%p,%p: stub\n", iface, xml);
527 return E_NOTIMPL;
530 static HRESULT WINAPI TaskSettings_put_XmlText(ITaskSettings *iface, BSTR xml)
532 FIXME("%p,%s: stub\n", iface, debugstr_w(xml));
533 return E_NOTIMPL;
536 static HRESULT WINAPI TaskSettings_get_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL *run)
538 TaskSettings *taskset = impl_from_ITaskSettings(iface);
540 TRACE("%p,%p\n", iface, run);
542 if (!run) return E_POINTER;
544 *run = taskset->run_only_if_network_available ? VARIANT_TRUE : VARIANT_FALSE;
546 return S_OK;
549 static HRESULT WINAPI TaskSettings_put_RunOnlyIfNetworkAvailable(ITaskSettings *iface, VARIANT_BOOL run)
551 FIXME("%p,%d: stub\n", iface, run);
552 return E_NOTIMPL;
555 static HRESULT WINAPI TaskSettings_get_ExecutionTimeLimit(ITaskSettings *iface, BSTR *limit)
557 TaskSettings *taskset = impl_from_ITaskSettings(iface);
559 TRACE("%p,%p\n", iface, limit);
561 if (!limit) return E_POINTER;
563 if (!taskset->execution_time_limit)
565 *limit = NULL;
566 return S_OK;
569 *limit = SysAllocString(taskset->execution_time_limit);
570 if (!*limit) return E_OUTOFMEMORY;
572 return S_OK;
575 static HRESULT WINAPI TaskSettings_put_ExecutionTimeLimit(ITaskSettings *iface, BSTR limit)
577 TRACE("%p,%s\n", iface, debugstr_w(limit));
578 return E_NOTIMPL;
581 static HRESULT WINAPI TaskSettings_get_Enabled(ITaskSettings *iface, VARIANT_BOOL *enabled)
583 TaskSettings *taskset = impl_from_ITaskSettings(iface);
585 TRACE("%p,%p\n", iface, enabled);
587 if (!enabled) return E_POINTER;
589 *enabled = taskset->enabled ? VARIANT_TRUE : VARIANT_FALSE;
591 return S_OK;
594 static HRESULT WINAPI TaskSettings_put_Enabled(ITaskSettings *iface, VARIANT_BOOL enabled)
596 FIXME("%p,%d: stub\n", iface, enabled);
597 return E_NOTIMPL;
600 static HRESULT WINAPI TaskSettings_get_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR *delay)
602 TaskSettings *taskset = impl_from_ITaskSettings(iface);
604 TRACE("%p,%p\n", iface, delay);
606 if (!delay) return E_POINTER;
608 if (!taskset->delete_expired_task_after)
610 *delay = NULL;
611 return S_OK;
614 *delay = SysAllocString(taskset->delete_expired_task_after);
615 if (!*delay) return E_OUTOFMEMORY;
617 return S_OK;
620 static HRESULT WINAPI TaskSettings_put_DeleteExpiredTaskAfter(ITaskSettings *iface, BSTR delay)
622 TRACE("%p,%s\n", iface, debugstr_w(delay));
623 return E_NOTIMPL;
626 static HRESULT WINAPI TaskSettings_get_Priority(ITaskSettings *iface, INT *priority)
628 TaskSettings *taskset = impl_from_ITaskSettings(iface);
630 TRACE("%p,%p\n", iface, priority);
632 if (!priority) return E_POINTER;
634 *priority = taskset->priority;
636 return S_OK;
639 static HRESULT WINAPI TaskSettings_put_Priority(ITaskSettings *iface, INT priority)
641 FIXME("%p,%d: stub\n", iface, priority);
642 return E_NOTIMPL;
645 static HRESULT WINAPI TaskSettings_get_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY *level)
647 TaskSettings *taskset = impl_from_ITaskSettings(iface);
649 TRACE("%p,%p\n", iface, level);
651 if (!level) return E_POINTER;
653 *level = taskset->compatibility;
655 return S_OK;
658 static HRESULT WINAPI TaskSettings_put_Compatibility(ITaskSettings *iface, TASK_COMPATIBILITY level)
660 FIXME("%p,%d: stub\n", iface, level);
661 return E_NOTIMPL;
664 static HRESULT WINAPI TaskSettings_get_Hidden(ITaskSettings *iface, VARIANT_BOOL *hidden)
666 TaskSettings *taskset = impl_from_ITaskSettings(iface);
668 TRACE("%p,%p\n", iface, hidden);
670 if (!hidden) return E_POINTER;
672 *hidden = taskset->hidden ? VARIANT_TRUE : VARIANT_FALSE;
674 return S_OK;
677 static HRESULT WINAPI TaskSettings_put_Hidden(ITaskSettings *iface, VARIANT_BOOL hidden)
679 FIXME("%p,%d: stub\n", iface, hidden);
680 return E_NOTIMPL;
683 static HRESULT WINAPI TaskSettings_get_IdleSettings(ITaskSettings *iface, IIdleSettings **settings)
685 FIXME("%p,%p: stub\n", iface, settings);
686 return E_NOTIMPL;
689 static HRESULT WINAPI TaskSettings_put_IdleSettings(ITaskSettings *iface, IIdleSettings *settings)
691 FIXME("%p,%p: stub\n", iface, settings);
692 return E_NOTIMPL;
695 static HRESULT WINAPI TaskSettings_get_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL *run)
697 TaskSettings *taskset = impl_from_ITaskSettings(iface);
699 TRACE("%p,%p\n", iface, run);
701 if (!run) return E_POINTER;
703 *run = taskset->run_only_if_idle ? VARIANT_TRUE : VARIANT_FALSE;
705 return S_OK;
708 static HRESULT WINAPI TaskSettings_put_RunOnlyIfIdle(ITaskSettings *iface, VARIANT_BOOL run)
710 FIXME("%p,%d: stub\n", iface, run);
711 return E_NOTIMPL;
714 static HRESULT WINAPI TaskSettings_get_WakeToRun(ITaskSettings *iface, VARIANT_BOOL *wake)
716 TaskSettings *taskset = impl_from_ITaskSettings(iface);
718 TRACE("%p,%p\n", iface, wake);
720 if (!wake) return E_POINTER;
722 *wake = taskset->wake_to_run ? VARIANT_TRUE : VARIANT_FALSE;
724 return S_OK;
727 static HRESULT WINAPI TaskSettings_put_WakeToRun(ITaskSettings *iface, VARIANT_BOOL wake)
729 FIXME("%p,%d: stub\n", iface, wake);
730 return E_NOTIMPL;
733 static HRESULT WINAPI TaskSettings_get_NetworkSettings(ITaskSettings *iface, INetworkSettings **settings)
735 FIXME("%p,%p: stub\n", iface, settings);
736 return E_NOTIMPL;
739 static HRESULT WINAPI TaskSettings_put_NetworkSettings(ITaskSettings *iface, INetworkSettings *settings)
741 FIXME("%p,%p: stub\n", iface, settings);
742 return E_NOTIMPL;
745 static const ITaskSettingsVtbl TaskSettings_vtbl =
747 TaskSettings_QueryInterface,
748 TaskSettings_AddRef,
749 TaskSettings_Release,
750 TaskSettings_GetTypeInfoCount,
751 TaskSettings_GetTypeInfo,
752 TaskSettings_GetIDsOfNames,
753 TaskSettings_Invoke,
754 TaskSettings_get_AllowDemandStart,
755 TaskSettings_put_AllowDemandStart,
756 TaskSettings_get_RestartInterval,
757 TaskSettings_put_RestartInterval,
758 TaskSettings_get_RestartCount,
759 TaskSettings_put_RestartCount,
760 TaskSettings_get_MultipleInstances,
761 TaskSettings_put_MultipleInstances,
762 TaskSettings_get_StopIfGoingOnBatteries,
763 TaskSettings_put_StopIfGoingOnBatteries,
764 TaskSettings_get_DisallowStartIfOnBatteries,
765 TaskSettings_put_DisallowStartIfOnBatteries,
766 TaskSettings_get_AllowHardTerminate,
767 TaskSettings_put_AllowHardTerminate,
768 TaskSettings_get_StartWhenAvailable,
769 TaskSettings_put_StartWhenAvailable,
770 TaskSettings_get_XmlText,
771 TaskSettings_put_XmlText,
772 TaskSettings_get_RunOnlyIfNetworkAvailable,
773 TaskSettings_put_RunOnlyIfNetworkAvailable,
774 TaskSettings_get_ExecutionTimeLimit,
775 TaskSettings_put_ExecutionTimeLimit,
776 TaskSettings_get_Enabled,
777 TaskSettings_put_Enabled,
778 TaskSettings_get_DeleteExpiredTaskAfter,
779 TaskSettings_put_DeleteExpiredTaskAfter,
780 TaskSettings_get_Priority,
781 TaskSettings_put_Priority,
782 TaskSettings_get_Compatibility,
783 TaskSettings_put_Compatibility,
784 TaskSettings_get_Hidden,
785 TaskSettings_put_Hidden,
786 TaskSettings_get_IdleSettings,
787 TaskSettings_put_IdleSettings,
788 TaskSettings_get_RunOnlyIfIdle,
789 TaskSettings_put_RunOnlyIfIdle,
790 TaskSettings_get_WakeToRun,
791 TaskSettings_put_WakeToRun,
792 TaskSettings_get_NetworkSettings,
793 TaskSettings_put_NetworkSettings
796 static HRESULT TaskSettings_create(ITaskSettings **obj)
798 static const WCHAR exec_time_limit[] = { 'P','T','7','2','H',0 };
799 TaskSettings *taskset;
801 taskset = heap_alloc(sizeof(*taskset));
802 if (!taskset) return E_OUTOFMEMORY;
804 taskset->ITaskSettings_iface.lpVtbl = &TaskSettings_vtbl;
805 taskset->ref = 1;
806 /* set the defaults */
807 taskset->restart_interval = NULL;
808 taskset->execution_time_limit = heap_strdupW(exec_time_limit);
809 taskset->delete_expired_task_after = NULL;
810 taskset->restart_count = 0;
811 taskset->priority = 7;
812 taskset->policy = TASK_INSTANCES_IGNORE_NEW;
813 taskset->compatibility = TASK_COMPATIBILITY_V2;
814 taskset->allow_on_demand_start = TRUE;
815 taskset->stop_if_going_on_batteries = TRUE;
816 taskset->disallow_start_if_on_batteries = TRUE;
817 taskset->allow_hard_terminate = TRUE;
818 taskset->start_when_available = FALSE;
819 taskset->run_only_if_network_available = FALSE;
820 taskset->enabled = TRUE;
821 taskset->hidden = FALSE;
822 taskset->run_only_if_idle = FALSE;
823 taskset->wake_to_run = FALSE;
825 *obj = &taskset->ITaskSettings_iface;
827 TRACE("created %p\n", *obj);
829 return S_OK;
832 typedef struct
834 ITaskDefinition ITaskDefinition_iface;
835 LONG ref;
836 IRegistrationInfo *reginfo;
837 ITaskSettings *taskset;
838 ITriggerCollection *triggers;
839 IPrincipal *principal;
840 IActionCollection *actions;
841 } TaskDefinition;
843 static inline TaskDefinition *impl_from_ITaskDefinition(ITaskDefinition *iface)
845 return CONTAINING_RECORD(iface, TaskDefinition, ITaskDefinition_iface);
848 static ULONG WINAPI TaskDefinition_AddRef(ITaskDefinition *iface)
850 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
851 return InterlockedIncrement(&taskdef->ref);
854 static ULONG WINAPI TaskDefinition_Release(ITaskDefinition *iface)
856 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
857 LONG ref = InterlockedDecrement(&taskdef->ref);
859 if (!ref)
861 TRACE("destroying %p\n", iface);
863 if (taskdef->reginfo)
864 IRegistrationInfo_Release(taskdef->reginfo);
865 if (taskdef->taskset)
866 ITaskSettings_Release(taskdef->taskset);
867 if (taskdef->triggers)
868 ITriggerCollection_Release(taskdef->triggers);
869 if (taskdef->principal)
870 IPrincipal_Release(taskdef->principal);
871 if (taskdef->actions)
872 IActionCollection_Release(taskdef->actions);
874 heap_free(taskdef);
877 return ref;
880 static HRESULT WINAPI TaskDefinition_QueryInterface(ITaskDefinition *iface, REFIID riid, void **obj)
882 if (!riid || !obj) return E_INVALIDARG;
884 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
886 if (IsEqualGUID(riid, &IID_ITaskDefinition) ||
887 IsEqualGUID(riid, &IID_IDispatch) ||
888 IsEqualGUID(riid, &IID_IUnknown))
890 ITaskDefinition_AddRef(iface);
891 *obj = iface;
892 return S_OK;
895 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
896 *obj = NULL;
897 return E_NOINTERFACE;
900 static HRESULT WINAPI TaskDefinition_GetTypeInfoCount(ITaskDefinition *iface, UINT *count)
902 FIXME("%p,%p: stub\n", iface, count);
903 return E_NOTIMPL;
906 static HRESULT WINAPI TaskDefinition_GetTypeInfo(ITaskDefinition *iface, UINT index, LCID lcid, ITypeInfo **info)
908 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
909 return E_NOTIMPL;
912 static HRESULT WINAPI TaskDefinition_GetIDsOfNames(ITaskDefinition *iface, REFIID riid, LPOLESTR *names,
913 UINT count, LCID lcid, DISPID *dispid)
915 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
916 return E_NOTIMPL;
919 static HRESULT WINAPI TaskDefinition_Invoke(ITaskDefinition *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
920 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
922 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
923 params, result, excepinfo, argerr);
924 return E_NOTIMPL;
927 static HRESULT WINAPI TaskDefinition_get_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo **info)
929 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
930 HRESULT hr;
932 TRACE("%p,%p\n", iface, info);
934 if (!info) return E_POINTER;
936 if (!taskdef->reginfo)
938 hr = RegistrationInfo_create(&taskdef->reginfo);
939 if (hr != S_OK) return hr;
942 IRegistrationInfo_AddRef(taskdef->reginfo);
943 *info = taskdef->reginfo;
945 return S_OK;
948 static HRESULT WINAPI TaskDefinition_put_RegistrationInfo(ITaskDefinition *iface, IRegistrationInfo *info)
950 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
952 TRACE("%p,%p\n", iface, info);
954 if (!info) return E_POINTER;
956 if (taskdef->reginfo)
957 IRegistrationInfo_Release(taskdef->reginfo);
959 IRegistrationInfo_AddRef(info);
960 taskdef->reginfo = info;
962 return S_OK;
965 static HRESULT WINAPI TaskDefinition_get_Triggers(ITaskDefinition *iface, ITriggerCollection **triggers)
967 FIXME("%p,%p: stub\n", iface, triggers);
968 return E_NOTIMPL;
971 static HRESULT WINAPI TaskDefinition_put_Triggers(ITaskDefinition *iface, ITriggerCollection *triggers)
973 FIXME("%p,%p: stub\n", iface, triggers);
974 return E_NOTIMPL;
977 static HRESULT WINAPI TaskDefinition_get_Settings(ITaskDefinition *iface, ITaskSettings **settings)
979 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
980 HRESULT hr;
982 TRACE("%p,%p\n", iface, settings);
984 if (!settings) return E_POINTER;
986 if (!taskdef->taskset)
988 hr = TaskSettings_create(&taskdef->taskset);
989 if (hr != S_OK) return hr;
992 ITaskSettings_AddRef(taskdef->taskset);
993 *settings = taskdef->taskset;
995 return S_OK;
998 static HRESULT WINAPI TaskDefinition_put_Settings(ITaskDefinition *iface, ITaskSettings *settings)
1000 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
1002 TRACE("%p,%p\n", iface, settings);
1004 if (!settings) return E_POINTER;
1006 if (taskdef->taskset)
1007 ITaskSettings_Release(taskdef->taskset);
1009 ITaskSettings_AddRef(settings);
1010 taskdef->taskset = settings;
1012 return S_OK;
1015 static HRESULT WINAPI TaskDefinition_get_Data(ITaskDefinition *iface, BSTR *data)
1017 FIXME("%p,%p: stub\n", iface, data);
1018 return E_NOTIMPL;
1021 static HRESULT WINAPI TaskDefinition_put_Data(ITaskDefinition *iface, BSTR data)
1023 FIXME("%p,%p: stub\n", iface, data);
1024 return E_NOTIMPL;
1027 static HRESULT WINAPI TaskDefinition_get_Principal(ITaskDefinition *iface, IPrincipal **principal)
1029 FIXME("%p,%p: stub\n", iface, principal);
1030 return E_NOTIMPL;
1033 static HRESULT WINAPI TaskDefinition_put_Principal(ITaskDefinition *iface, IPrincipal *principal)
1035 FIXME("%p,%p: stub\n", iface, principal);
1036 return E_NOTIMPL;
1039 static HRESULT WINAPI TaskDefinition_get_Actions(ITaskDefinition *iface, IActionCollection **actions)
1041 FIXME("%p,%p: stub\n", iface, actions);
1042 return E_NOTIMPL;
1045 static HRESULT WINAPI TaskDefinition_put_Actions(ITaskDefinition *iface, IActionCollection *actions)
1047 FIXME("%p,%p: stub\n", iface, actions);
1048 return E_NOTIMPL;
1051 static const WCHAR Task[] = {'T','a','s','k',0};
1052 static const WCHAR version[] = {'v','e','r','s','i','o','n',0};
1053 static const WCHAR v1_0[] = {'1','.','0',0};
1054 static const WCHAR v1_1[] = {'1','.','1',0};
1055 static const WCHAR v1_2[] = {'1','.','2',0};
1056 static const WCHAR v1_3[] = {'1','.','3',0};
1057 static const WCHAR xmlns[] = {'x','m','l','n','s',0};
1058 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};
1059 static const WCHAR RegistrationInfo[] = {'R','e','g','i','s','t','r','a','t','i','o','n','I','n','f','o',0};
1060 static const WCHAR Author[] = {'A','u','t','h','o','r',0};
1061 static const WCHAR Description[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
1062 static const WCHAR Source[] = {'S','o','u','r','c','e',0};
1063 static const WCHAR Date[] = {'D','a','t','e',0};
1064 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
1065 static const WCHAR Documentation[] = {'D','o','c','u','m','e','n','t','a','t','i','o','n',0};
1066 static const WCHAR URI[] = {'U','R','I',0};
1067 static const WCHAR SecurityDescriptor[] = {'S','e','c','u','r','i','t','y','D','e','s','c','r','i','p','t','o','r',0};
1068 static const WCHAR Settings[] = {'S','e','t','t','i','n','g','s',0};
1069 static const WCHAR Triggers[] = {'T','r','i','g','g','e','r','s',0};
1070 static const WCHAR Principals[] = {'P','r','i','n','c','i','p','a','l','s',0};
1071 static const WCHAR Principal[] = {'P','r','i','n','c','i','p','a','l',0};
1072 static const WCHAR id[] = {'i','d',0};
1073 static const WCHAR UserId[] = {'U','s','e','r','I','d',0};
1074 static const WCHAR LogonType[] = {'L','o','g','o','n','T','y','p','e',0};
1075 static const WCHAR GroupId[] = {'G','r','o','u','p','I','d',0};
1076 static const WCHAR DisplayName[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
1077 static const WCHAR HighestAvailable[] = {'H','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
1078 static const WCHAR Password[] = {'P','a','s','s','w','o','r','d',0};
1079 static const WCHAR S4U[] = {'S','4','U',0};
1080 static const WCHAR InteractiveToken[] = {'I','n','t','e','r','a','c','t','i','v','e','T','o','k','e','n',0};
1081 static const WCHAR RunLevel[] = {'R','u','n','L','e','v','e','l',0};
1082 static const WCHAR LeastPrivilege[] = {'L','e','a','s','t','P','r','i','v','i','l','e','g','e',0};
1083 static const WCHAR Actions[] = {'A','c','t','i','o','n','s',0};
1084 static const WCHAR Exec[] = {'E','x','e','c',0};
1085 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};
1086 static const WCHAR IgnoreNew[] = {'I','g','n','o','r','e','N','e','w',0};
1087 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};
1088 static const WCHAR AllowStartOnDemand[] = {'A','l','l','o','w','S','t','a','r','t','O','n','D','e','m','a','n','d',0};
1089 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};
1090 static const WCHAR AllowHardTerminate[] = {'A','l','l','o','w','H','a','r','d','T','e','r','m','i','n','a','t','e',0};
1091 static const WCHAR StartWhenAvailable[] = {'S','t','a','r','t','W','h','e','n','A','v','a','i','l','a','b','l','e',0};
1092 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};
1093 static const WCHAR Enabled[] = {'E','n','a','b','l','e','d',0};
1094 static const WCHAR Hidden[] = {'H','i','d','d','e','n',0};
1095 static const WCHAR RunOnlyIfIdle[] = {'R','u','n','O','n','l','y','I','f','I','d','l','e',0};
1096 static const WCHAR WakeToRun[] = {'W','a','k','e','T','o','R','u','n',0};
1097 static const WCHAR ExecutionTimeLimit[] = {'E','x','e','c','u','t','i','o','n','T','i','m','e','L','i','m','i','t',0};
1098 static const WCHAR Priority[] = {'P','r','i','o','r','i','t','y',0};
1099 static const WCHAR IdleSettings[] = {'I','d','l','e','S','e','t','t','i','n','g','s',0};
1101 static int xml_indent;
1103 static inline void push_indent(void)
1105 xml_indent += 2;
1108 static inline void pop_indent(void)
1110 xml_indent -= 2;
1113 static inline HRESULT write_stringW(IStream *stream, const WCHAR *str)
1115 return IStream_Write(stream, str, lstrlenW(str) * sizeof(WCHAR), NULL);
1118 static void write_indent(IStream *stream)
1120 static const WCHAR spacesW[] = {' ',' ',0};
1121 int i;
1122 for (i = 0; i < xml_indent; i += 2)
1123 write_stringW(stream, spacesW);
1126 static const WCHAR start_element[] = {'<',0};
1127 static const WCHAR start_end_element[] = {'<','/',0};
1128 static const WCHAR close_element[] = {'>',0};
1129 static const WCHAR end_empty_element[] = {'/','>',0};
1130 static const WCHAR eol[] = {'\n',0};
1131 static const WCHAR spaceW[] = {' ',0};
1132 static const WCHAR equalW[] = {'=',0};
1133 static const WCHAR quoteW[] = {'"',0};
1135 static inline HRESULT write_empty_element(IStream *stream, const WCHAR *name)
1137 write_indent(stream);
1138 write_stringW(stream, start_element);
1139 write_stringW(stream, name);
1140 write_stringW(stream, end_empty_element);
1141 return write_stringW(stream, eol);
1144 static inline HRESULT write_element(IStream *stream, const WCHAR *name)
1146 write_indent(stream);
1147 write_stringW(stream, start_element);
1148 write_stringW(stream, name);
1149 write_stringW(stream, close_element);
1150 return write_stringW(stream, eol);
1153 static inline HRESULT write_element_end(IStream *stream, const WCHAR *name)
1155 write_indent(stream);
1156 write_stringW(stream, start_end_element);
1157 write_stringW(stream, name);
1158 write_stringW(stream, close_element);
1159 return write_stringW(stream, eol);
1162 static inline HRESULT write_text_value(IStream *stream, const WCHAR *name, const WCHAR *value)
1164 write_indent(stream);
1165 write_stringW(stream, start_element);
1166 write_stringW(stream, name);
1167 write_stringW(stream, close_element);
1168 write_stringW(stream, value);
1169 write_stringW(stream, start_end_element);
1170 write_stringW(stream, name);
1171 write_stringW(stream, close_element);
1172 return write_stringW(stream, eol);
1175 static HRESULT write_task_attributes(IStream *stream, ITaskDefinition *taskdef)
1177 HRESULT hr;
1178 ITaskSettings *taskset;
1179 TASK_COMPATIBILITY level;
1180 const WCHAR *compatibility;
1182 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
1183 if (hr != S_OK) return hr;
1185 hr = ITaskSettings_get_Compatibility(taskset, &level);
1186 if (hr != S_OK) level = TASK_COMPATIBILITY_V2_1;
1188 ITaskSettings_Release(taskset);
1190 switch (level)
1192 case TASK_COMPATIBILITY_AT:
1193 compatibility = v1_0;
1194 break;
1195 case TASK_COMPATIBILITY_V1:
1196 compatibility = v1_1;
1197 break;
1198 case TASK_COMPATIBILITY_V2:
1199 compatibility = v1_2;
1200 break;
1201 default:
1202 compatibility = v1_3;
1203 break;
1206 write_stringW(stream, start_element);
1207 write_stringW(stream, Task);
1208 write_stringW(stream, spaceW);
1209 write_stringW(stream, version);
1210 write_stringW(stream, equalW);
1211 write_stringW(stream, quoteW);
1212 write_stringW(stream, compatibility);
1213 write_stringW(stream, quoteW);
1214 write_stringW(stream, spaceW);
1215 write_stringW(stream, xmlns);
1216 write_stringW(stream, equalW);
1217 write_stringW(stream, quoteW);
1218 write_stringW(stream, task_ns);
1219 write_stringW(stream, quoteW);
1220 write_stringW(stream, close_element);
1221 return write_stringW(stream, eol);
1224 static HRESULT write_registration_info(IStream *stream, IRegistrationInfo *reginfo)
1226 HRESULT hr;
1227 BSTR bstr;
1228 VARIANT var;
1230 if (!reginfo)
1231 return write_empty_element(stream, RegistrationInfo);
1233 hr = write_element(stream, RegistrationInfo);
1234 if (hr != S_OK) return hr;
1236 push_indent();
1238 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
1239 if (hr == S_OK)
1241 hr = write_text_value(stream, Source, bstr);
1242 SysFreeString(bstr);
1243 if (hr != S_OK) return hr;
1245 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
1246 if (hr == S_OK)
1248 hr = write_text_value(stream, Date, bstr);
1249 SysFreeString(bstr);
1250 if (hr != S_OK) return hr;
1252 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
1253 if (hr == S_OK)
1255 hr = write_text_value(stream, Author, bstr);
1256 SysFreeString(bstr);
1257 if (hr != S_OK) return hr;
1259 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
1260 if (hr == S_OK)
1262 hr = write_text_value(stream, Version, bstr);
1263 SysFreeString(bstr);
1264 if (hr != S_OK) return hr;
1266 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
1267 if (hr == S_OK)
1269 hr = write_text_value(stream, Description, bstr);
1270 SysFreeString(bstr);
1271 if (hr != S_OK) return hr;
1273 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
1274 if (hr == S_OK)
1276 hr = write_text_value(stream, Documentation, bstr);
1277 SysFreeString(bstr);
1278 if (hr != S_OK) return hr;
1280 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
1281 if (hr == S_OK)
1283 hr = write_text_value(stream, URI, bstr);
1284 SysFreeString(bstr);
1285 if (hr != S_OK) return hr;
1287 hr = IRegistrationInfo_get_SecurityDescriptor(reginfo, &var);
1288 if (hr == S_OK)
1290 if (V_VT(&var) == VT_BSTR)
1292 hr = write_text_value(stream, SecurityDescriptor, V_BSTR(&var));
1293 VariantClear(&var);
1294 if (hr != S_OK) return hr;
1296 else
1297 FIXME("SecurityInfo variant type %d is not supported\n", V_VT(&var));
1300 pop_indent();
1302 return write_element_end(stream, RegistrationInfo);
1305 static HRESULT write_principal(IStream *stream, IPrincipal *principal)
1307 HRESULT hr;
1308 BSTR bstr;
1309 TASK_LOGON_TYPE logon;
1310 TASK_RUNLEVEL_TYPE level;
1312 if (!principal)
1313 return write_empty_element(stream, Principals);
1315 hr = write_element(stream, Principals);
1316 if (hr != S_OK) return hr;
1318 push_indent();
1320 hr = IPrincipal_get_Id(principal, &bstr);
1321 if (hr == S_OK)
1323 write_indent(stream);
1324 write_stringW(stream, start_element);
1325 write_stringW(stream, Principal);
1326 write_stringW(stream, spaceW);
1327 write_stringW(stream, id);
1328 write_stringW(stream, equalW);
1329 write_stringW(stream, quoteW);
1330 write_stringW(stream, bstr);
1331 write_stringW(stream, quoteW);
1332 write_stringW(stream, close_element);
1333 write_stringW(stream, eol);
1334 SysFreeString(bstr);
1336 else
1337 write_element(stream, Principal);
1339 push_indent();
1341 hr = IPrincipal_get_GroupId(principal, &bstr);
1342 if (hr == S_OK)
1344 hr = write_text_value(stream, GroupId, bstr);
1345 SysFreeString(bstr);
1346 if (hr != S_OK) return hr;
1348 hr = IPrincipal_get_DisplayName(principal, &bstr);
1349 if (hr == S_OK)
1351 hr = write_text_value(stream, DisplayName, bstr);
1352 SysFreeString(bstr);
1353 if (hr != S_OK) return hr;
1355 hr = IPrincipal_get_UserId(principal, &bstr);
1356 if (hr == S_OK && lstrlenW(bstr))
1358 hr = write_text_value(stream, UserId, bstr);
1359 SysFreeString(bstr);
1360 if (hr != S_OK) return hr;
1362 hr = IPrincipal_get_RunLevel(principal, &level);
1363 if (hr == S_OK)
1365 const WCHAR *level_str = NULL;
1367 switch (level)
1369 case TASK_RUNLEVEL_HIGHEST:
1370 level_str = HighestAvailable;
1371 break;
1372 case TASK_RUNLEVEL_LUA:
1373 level_str = LeastPrivilege;
1374 break;
1375 default:
1376 FIXME("Principal run level %d\n", level);
1377 break;
1380 if (level_str)
1382 hr = write_text_value(stream, RunLevel, level_str);
1383 if (hr != S_OK) return hr;
1386 hr = IPrincipal_get_LogonType(principal, &logon);
1387 if (hr == S_OK)
1389 const WCHAR *logon_str = NULL;
1391 switch (logon)
1393 case TASK_LOGON_PASSWORD:
1394 logon_str = Password;
1395 break;
1396 case TASK_LOGON_S4U:
1397 logon_str = S4U;
1398 break;
1399 case TASK_LOGON_INTERACTIVE_TOKEN:
1400 logon_str = InteractiveToken;
1401 break;
1402 default:
1403 FIXME("Principal logon type %d\n", logon);
1404 break;
1407 if (logon_str)
1409 hr = write_text_value(stream, LogonType, logon_str);
1410 if (hr != S_OK) return hr;
1414 pop_indent();
1415 write_element_end(stream, Principal);
1417 pop_indent();
1418 return write_element_end(stream, Principals);
1421 static HRESULT write_settings(IStream *stream, ITaskSettings *settings)
1423 if (!settings)
1424 return write_empty_element(stream, Settings);
1426 FIXME("stub\n");
1427 return S_OK;
1430 static HRESULT write_triggers(IStream *stream, ITriggerCollection *triggers)
1432 if (!triggers)
1433 return write_empty_element(stream, Triggers);
1435 FIXME("stub\n");
1436 return S_OK;
1439 static HRESULT write_actions(IStream *stream, IActionCollection *actions)
1441 if (!actions)
1443 write_element(stream, Actions);
1444 push_indent();
1445 write_empty_element(stream, Exec);
1446 pop_indent();
1447 return write_element_end(stream, Actions);
1450 FIXME("stub\n");
1451 return S_OK;
1454 static HRESULT WINAPI TaskDefinition_get_XmlText(ITaskDefinition *iface, BSTR *xml)
1456 TaskDefinition *taskdef = impl_from_ITaskDefinition(iface);
1457 HRESULT hr;
1458 IStream *stream;
1459 HGLOBAL hmem;
1460 void *p;
1462 TRACE("%p,%p\n", iface, xml);
1464 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16);
1465 if (!hmem) return E_OUTOFMEMORY;
1467 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
1468 if (hr != S_OK)
1470 GlobalFree(hmem);
1471 return hr;
1474 hr = write_task_attributes(stream, &taskdef->ITaskDefinition_iface);
1475 if (hr != S_OK) goto failed;
1477 push_indent();
1479 hr = write_registration_info(stream, taskdef->reginfo);
1480 if (hr != S_OK) goto failed;
1482 hr = write_triggers(stream, taskdef->triggers);
1483 if (hr != S_OK) goto failed;
1485 hr = write_principal(stream, taskdef->principal);
1486 if (hr != S_OK) goto failed;
1488 hr = write_settings(stream, taskdef->taskset);
1489 if (hr != S_OK) goto failed;
1491 hr = write_actions(stream, taskdef->actions);
1492 if (hr != S_OK) goto failed;
1494 pop_indent();
1496 write_element_end(stream, Task);
1497 IStream_Write(stream, "\0\0", 2, NULL);
1499 p = GlobalLock(hmem);
1500 *xml = SysAllocString(p);
1501 GlobalUnlock(hmem);
1503 IStream_Release(stream);
1505 return *xml ? S_OK : E_OUTOFMEMORY;
1507 failed:
1508 IStream_Release(stream);
1509 return hr;
1512 static HRESULT read_text_value(IXmlReader *reader, WCHAR **value)
1514 HRESULT hr;
1515 XmlNodeType type;
1517 while (IXmlReader_Read(reader, &type) == S_OK)
1519 switch (type)
1521 case XmlNodeType_Text:
1522 hr = IXmlReader_GetValue(reader, (const WCHAR **)value, NULL);
1523 if (hr != S_OK) return hr;
1524 TRACE("%s\n", debugstr_w(*value));
1525 return S_OK;
1527 case XmlNodeType_Whitespace:
1528 case XmlNodeType_Comment:
1529 break;
1531 default:
1532 FIXME("unexpected node type %d\n", type);
1533 return E_FAIL;
1537 return E_FAIL;
1540 static HRESULT read_variantbool_value(IXmlReader *reader, VARIANT_BOOL *vbool)
1542 static const WCHAR trueW[] = {'t','r','u','e',0};
1543 static const WCHAR falseW[] = {'f','a','l','s','e',0};
1544 HRESULT hr;
1545 WCHAR *value;
1547 hr = read_text_value(reader, &value);
1548 if (hr != S_OK) return hr;
1550 if (!lstrcmpW(value, trueW))
1551 *vbool = VARIANT_TRUE;
1552 else if (!lstrcmpW(value, falseW))
1553 *vbool = VARIANT_FALSE;
1554 else
1556 FIXME("unexpected bool value %s\n", debugstr_w(value));
1557 return E_FAIL;
1560 return S_OK;
1563 static HRESULT read_int_value(IXmlReader *reader, int *int_val)
1565 HRESULT hr;
1566 WCHAR *value;
1568 hr = read_text_value(reader, &value);
1569 if (hr != S_OK) return hr;
1571 *int_val = strtolW(value, NULL, 10);
1573 return S_OK;
1576 static HRESULT read_triggers(IXmlReader *reader, ITaskDefinition *taskdef)
1578 FIXME("stub\n");
1579 return S_OK;
1582 static HRESULT read_principal_attributes(IXmlReader *reader, IPrincipal *principal)
1584 HRESULT hr;
1585 const WCHAR *name;
1586 const WCHAR *value;
1588 hr = IXmlReader_MoveToFirstAttribute(reader);
1590 while (hr == S_OK)
1592 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1593 if (hr != S_OK) break;
1595 hr = IXmlReader_GetValue(reader, &value, NULL);
1596 if (hr != S_OK) break;
1598 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
1600 if (!lstrcmpW(name, id))
1601 IPrincipal_put_Id(principal, (BSTR)value);
1602 else
1603 FIXME("unhandled Principal attribute %s\n", debugstr_w(name));
1605 hr = IXmlReader_MoveToNextAttribute(reader);
1608 return S_OK;
1611 static HRESULT read_principal(IXmlReader *reader, IPrincipal *principal)
1613 HRESULT hr;
1614 XmlNodeType type;
1615 const WCHAR *name;
1616 WCHAR *value;
1618 if (IXmlReader_IsEmptyElement(reader))
1620 TRACE("Principal is empty\n");
1621 return S_OK;
1624 read_principal_attributes(reader, principal);
1626 while (IXmlReader_Read(reader, &type) == S_OK)
1628 switch (type)
1630 case XmlNodeType_EndElement:
1631 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1632 if (hr != S_OK) return hr;
1634 TRACE("/%s\n", debugstr_w(name));
1636 if (!lstrcmpW(name, Principal))
1637 return S_OK;
1639 break;
1641 case XmlNodeType_Element:
1642 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1643 if (hr != S_OK) return hr;
1645 TRACE("Element: %s\n", debugstr_w(name));
1647 if (!lstrcmpW(name, UserId))
1649 hr = read_text_value(reader, &value);
1650 if (hr == S_OK)
1651 IPrincipal_put_UserId(principal, value);
1653 else if (!lstrcmpW(name, LogonType))
1655 hr = read_text_value(reader, &value);
1656 if (hr == S_OK)
1658 TASK_LOGON_TYPE logon = TASK_LOGON_NONE;
1660 if (!lstrcmpW(value, InteractiveToken))
1661 logon = TASK_LOGON_INTERACTIVE_TOKEN;
1662 else
1663 FIXME("unhandled LogonType %s\n", debugstr_w(value));
1665 IPrincipal_put_LogonType(principal, logon);
1668 else if (!lstrcmpW(name, RunLevel))
1670 hr = read_text_value(reader, &value);
1671 if (hr == S_OK)
1673 TASK_RUNLEVEL_TYPE level = TASK_RUNLEVEL_LUA;
1675 if (!lstrcmpW(value, LeastPrivilege))
1676 level = TASK_RUNLEVEL_LUA;
1677 else
1678 FIXME("unhandled RunLevel %s\n", debugstr_w(value));
1680 IPrincipal_put_RunLevel(principal, level);
1683 else
1684 FIXME("unhandled Principal element %s\n", debugstr_w(name));
1686 break;
1688 case XmlNodeType_Whitespace:
1689 case XmlNodeType_Comment:
1690 break;
1692 default:
1693 FIXME("unhandled Principal node type %d\n", type);
1694 break;
1698 WARN("Principal was not terminated\n");
1699 return E_FAIL;
1702 static HRESULT read_principals(IXmlReader *reader, ITaskDefinition *taskdef)
1704 HRESULT hr;
1705 XmlNodeType type;
1706 const WCHAR *name;
1708 if (IXmlReader_IsEmptyElement(reader))
1710 TRACE("Principals is empty\n");
1711 return S_OK;
1714 while (IXmlReader_Read(reader, &type) == S_OK)
1716 switch (type)
1718 case XmlNodeType_EndElement:
1719 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1720 if (hr != S_OK) return hr;
1722 TRACE("/%s\n", debugstr_w(name));
1724 if (!lstrcmpW(name, Principals))
1725 return S_OK;
1727 break;
1729 case XmlNodeType_Element:
1730 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1731 if (hr != S_OK) return hr;
1733 TRACE("Element: %s\n", debugstr_w(name));
1735 if (!lstrcmpW(name, Principal))
1737 IPrincipal *principal;
1739 hr = ITaskDefinition_get_Principal(taskdef, &principal);
1740 if (hr != S_OK) return hr;
1741 hr = read_principal(reader, principal);
1742 IPrincipal_Release(principal);
1744 else
1745 FIXME("unhandled Principals element %s\n", debugstr_w(name));
1747 break;
1749 case XmlNodeType_Whitespace:
1750 case XmlNodeType_Comment:
1751 break;
1753 default:
1754 FIXME("unhandled Principals node type %d\n", type);
1755 break;
1759 WARN("Principals was not terminated\n");
1760 return E_FAIL;
1763 static HRESULT read_actions(IXmlReader *reader, ITaskDefinition *taskdef)
1765 FIXME("stub\n");
1766 return S_OK;
1769 static HRESULT read_idle_settings(IXmlReader *reader, ITaskSettings *taskset)
1771 FIXME("stub\n");
1772 return S_OK;
1775 static HRESULT read_settings(IXmlReader *reader, ITaskSettings *taskset)
1777 HRESULT hr;
1778 XmlNodeType type;
1779 const WCHAR *name;
1780 WCHAR *value;
1781 VARIANT_BOOL bool_val;
1782 int int_val;
1784 if (IXmlReader_IsEmptyElement(reader))
1786 TRACE("Settings is empty\n");
1787 return S_OK;
1790 while (IXmlReader_Read(reader, &type) == S_OK)
1792 switch (type)
1794 case XmlNodeType_EndElement:
1795 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1796 if (hr != S_OK) return hr;
1798 TRACE("/%s\n", debugstr_w(name));
1800 if (!lstrcmpW(name, Settings))
1801 return S_OK;
1803 break;
1805 case XmlNodeType_Element:
1806 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1807 if (hr != S_OK) return hr;
1809 TRACE("Element: %s\n", debugstr_w(name));
1811 if (!lstrcmpW(name, MultipleInstancesPolicy))
1813 hr = read_text_value(reader, &value);
1814 if (hr == S_OK)
1816 int_val = TASK_INSTANCES_IGNORE_NEW;
1818 if (!lstrcmpW(value, IgnoreNew))
1819 int_val = TASK_INSTANCES_IGNORE_NEW;
1820 else
1821 FIXME("unhandled MultipleInstancesPolicy %s\n", debugstr_w(value));
1823 ITaskSettings_put_MultipleInstances(taskset, int_val);
1826 else if (!lstrcmpW(name, DisallowStartIfOnBatteries))
1828 hr = read_variantbool_value(reader, &bool_val);
1829 if (hr == S_OK)
1830 ITaskSettings_put_DisallowStartIfOnBatteries(taskset, bool_val);
1832 else if (!lstrcmpW(name, AllowStartOnDemand))
1834 hr = read_variantbool_value(reader, &bool_val);
1835 if (hr == S_OK)
1836 ITaskSettings_put_AllowDemandStart(taskset, bool_val);
1838 else if (!lstrcmpW(name, StopIfGoingOnBatteries))
1840 hr = read_variantbool_value(reader, &bool_val);
1841 if (hr == S_OK)
1842 ITaskSettings_put_StopIfGoingOnBatteries(taskset, bool_val);
1844 else if (!lstrcmpW(name, AllowHardTerminate))
1846 hr = read_variantbool_value(reader, &bool_val);
1847 if (hr == S_OK)
1848 ITaskSettings_put_AllowHardTerminate(taskset, bool_val);
1850 else if (!lstrcmpW(name, StartWhenAvailable))
1852 hr = read_variantbool_value(reader, &bool_val);
1853 if (hr == S_OK)
1854 ITaskSettings_put_StartWhenAvailable(taskset, bool_val);
1856 else if (!lstrcmpW(name, RunOnlyIfNetworkAvailable))
1858 hr = read_variantbool_value(reader, &bool_val);
1859 if (hr == S_OK)
1860 ITaskSettings_put_RunOnlyIfNetworkAvailable(taskset, bool_val);
1862 else if (!lstrcmpW(name, Enabled))
1864 hr = read_variantbool_value(reader, &bool_val);
1865 if (hr == S_OK)
1866 ITaskSettings_put_Enabled(taskset, bool_val);
1868 else if (!lstrcmpW(name, Hidden))
1870 hr = read_variantbool_value(reader, &bool_val);
1871 if (hr == S_OK)
1872 ITaskSettings_put_Hidden(taskset, bool_val);
1874 else if (!lstrcmpW(name, RunOnlyIfIdle))
1876 hr = read_variantbool_value(reader, &bool_val);
1877 if (hr == S_OK)
1878 ITaskSettings_put_RunOnlyIfIdle(taskset, bool_val);
1880 else if (!lstrcmpW(name, WakeToRun))
1882 hr = read_variantbool_value(reader, &bool_val);
1883 if (hr == S_OK)
1884 ITaskSettings_put_WakeToRun(taskset, bool_val);
1886 else if (!lstrcmpW(name, ExecutionTimeLimit))
1888 hr = read_text_value(reader, &value);
1889 if (hr == S_OK)
1890 ITaskSettings_put_ExecutionTimeLimit(taskset, value);
1892 else if (!lstrcmpW(name, Priority))
1894 hr = read_int_value(reader, &int_val);
1895 if (hr == S_OK)
1896 ITaskSettings_put_Priority(taskset, int_val);
1898 else if (!lstrcmpW(name, IdleSettings))
1900 hr = read_idle_settings(reader, taskset);
1901 if (hr != S_OK) return hr;
1903 else
1904 FIXME("unhandled Settings element %s\n", debugstr_w(name));
1906 break;
1908 case XmlNodeType_Whitespace:
1909 case XmlNodeType_Comment:
1910 break;
1912 default:
1913 FIXME("unhandled Settings node type %d\n", type);
1914 break;
1918 WARN("Settings was not terminated\n");
1919 return E_FAIL;
1922 static HRESULT read_registration_info(IXmlReader *reader, IRegistrationInfo *info)
1924 HRESULT hr;
1925 XmlNodeType type;
1926 const WCHAR *name;
1927 WCHAR *value;
1929 if (IXmlReader_IsEmptyElement(reader))
1931 TRACE("RegistrationInfo is empty\n");
1932 return S_OK;
1935 while (IXmlReader_Read(reader, &type) == S_OK)
1937 switch (type)
1939 case XmlNodeType_EndElement:
1940 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1941 if (hr != S_OK) return hr;
1943 TRACE("/%s\n", debugstr_w(name));
1945 if (!lstrcmpW(name, RegistrationInfo))
1946 return S_OK;
1948 break;
1950 case XmlNodeType_Element:
1951 hr = IXmlReader_GetLocalName(reader, &name, NULL);
1952 if (hr != S_OK) return hr;
1954 TRACE("Element: %s\n", debugstr_w(name));
1956 if (!lstrcmpW(name, Author))
1958 hr = read_text_value(reader, &value);
1959 if (hr == S_OK)
1960 IRegistrationInfo_put_Author(info, value);
1962 else if (!lstrcmpW(name, Description))
1964 hr = read_text_value(reader, &value);
1965 if (hr == S_OK)
1966 IRegistrationInfo_put_Description(info, value);
1968 else
1969 FIXME("unhandled RegistrationInfo element %s\n", debugstr_w(name));
1971 break;
1973 case XmlNodeType_Whitespace:
1974 case XmlNodeType_Comment:
1975 break;
1977 default:
1978 FIXME("unhandled RegistrationInfo node type %d\n", type);
1979 break;
1983 WARN("RegistrationInfo was not terminated\n");
1984 return E_FAIL;
1987 static HRESULT read_task_attributes(IXmlReader *reader, ITaskDefinition *taskdef)
1989 HRESULT hr;
1990 ITaskSettings *taskset;
1991 const WCHAR *name;
1992 const WCHAR *value;
1993 BOOL xmlns_ok = FALSE;
1995 TRACE("\n");
1997 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
1998 if (hr != S_OK) return hr;
2000 hr = IXmlReader_MoveToFirstAttribute(reader);
2002 while (hr == S_OK)
2004 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2005 if (hr != S_OK) break;
2007 hr = IXmlReader_GetValue(reader, &value, NULL);
2008 if (hr != S_OK) break;
2010 TRACE("%s=%s\n", debugstr_w(name), debugstr_w(value));
2012 if (!lstrcmpW(name, version))
2014 TASK_COMPATIBILITY compatibility = TASK_COMPATIBILITY_V2;
2016 if (!lstrcmpW(value, v1_0))
2017 compatibility = TASK_COMPATIBILITY_AT;
2018 else if (!lstrcmpW(value, v1_1))
2019 compatibility = TASK_COMPATIBILITY_V1;
2020 else if (!lstrcmpW(value, v1_2))
2021 compatibility = TASK_COMPATIBILITY_V2;
2022 else if (!lstrcmpW(value, v1_3))
2023 compatibility = TASK_COMPATIBILITY_V2_1;
2024 else
2025 FIXME("unknown version %s\n", debugstr_w(value));
2027 ITaskSettings_put_Compatibility(taskset, compatibility);
2029 else if (!lstrcmpW(name, xmlns))
2031 if (lstrcmpW(value, task_ns))
2033 FIXME("unknown namespace %s\n", debugstr_w(value));
2034 break;
2036 xmlns_ok = TRUE;
2038 else
2039 FIXME("unhandled Task attribute %s\n", debugstr_w(name));
2041 hr = IXmlReader_MoveToNextAttribute(reader);
2044 ITaskSettings_Release(taskset);
2045 return xmlns_ok ? S_OK : SCHED_E_NAMESPACE;
2048 static HRESULT read_task(IXmlReader *reader, ITaskDefinition *taskdef)
2050 HRESULT hr;
2051 XmlNodeType type;
2052 const WCHAR *name;
2054 if (IXmlReader_IsEmptyElement(reader))
2056 TRACE("Task is empty\n");
2057 return S_OK;
2060 while (IXmlReader_Read(reader, &type) == S_OK)
2062 switch (type)
2064 case XmlNodeType_EndElement:
2065 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2066 if (hr != S_OK) return hr;
2068 TRACE("/%s\n", debugstr_w(name));
2070 if (!lstrcmpW(name, Task))
2071 return S_OK;
2073 break;
2075 case XmlNodeType_Element:
2076 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2077 if (hr != S_OK) return hr;
2079 TRACE("Element: %s\n", debugstr_w(name));
2081 if (!lstrcmpW(name, RegistrationInfo))
2083 IRegistrationInfo *info;
2085 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &info);
2086 if (hr != S_OK) return hr;
2087 hr = read_registration_info(reader, info);
2088 IRegistrationInfo_Release(info);
2090 else if (!lstrcmpW(name, Settings))
2092 ITaskSettings *taskset;
2094 hr = ITaskDefinition_get_Settings(taskdef, &taskset);
2095 if (hr != S_OK) return hr;
2096 hr = read_settings(reader, taskset);
2097 ITaskSettings_Release(taskset);
2099 else if (!lstrcmpW(name, Triggers))
2100 hr = read_triggers(reader, taskdef);
2101 else if (!lstrcmpW(name, Principals))
2102 hr = read_principals(reader, taskdef);
2103 else if (!lstrcmpW(name, Actions))
2104 hr = read_actions(reader, taskdef);
2105 else
2106 FIXME("unhandled Task element %s\n", debugstr_w(name));
2108 if (hr != S_OK) return hr;
2109 break;
2111 case XmlNodeType_Comment:
2112 case XmlNodeType_Whitespace:
2113 break;
2115 default:
2116 FIXME("unhandled Task node type %d\n", type);
2117 break;
2121 WARN("Task was not terminated\n");
2122 return E_FAIL;
2125 static HRESULT read_xml(IXmlReader *reader, ITaskDefinition *taskdef)
2127 HRESULT hr;
2128 XmlNodeType type;
2129 const WCHAR *name;
2131 while (IXmlReader_Read(reader, &type) == S_OK)
2133 switch (type)
2135 case XmlNodeType_XmlDeclaration:
2136 TRACE("XmlDeclaration\n");
2137 break;
2139 case XmlNodeType_Element:
2140 hr = IXmlReader_GetLocalName(reader, &name, NULL);
2141 if (hr != S_OK) return hr;
2143 TRACE("Element: %s\n", debugstr_w(name));
2145 if (!lstrcmpW(name, Task))
2147 hr = read_task_attributes(reader, taskdef);
2148 if (hr != S_OK) return hr;
2150 return read_task(reader, taskdef);
2152 else
2153 FIXME("unhandled XML element %s\n", debugstr_w(name));
2155 break;
2157 case XmlNodeType_Comment:
2158 case XmlNodeType_Whitespace:
2159 break;
2161 default:
2162 FIXME("unhandled XML node type %d\n", type);
2163 break;
2167 WARN("Task definition was not found\n");
2168 return E_FAIL;
2171 static HRESULT WINAPI TaskDefinition_put_XmlText(ITaskDefinition *iface, BSTR xml)
2173 HRESULT hr;
2174 IStream *stream;
2175 IXmlReader *reader;
2176 HGLOBAL hmem;
2177 void *buf;
2179 TRACE("%p,%s\n", iface, debugstr_w(xml));
2181 if (!xml) return E_INVALIDARG;
2183 hmem = GlobalAlloc(0, lstrlenW(xml) * sizeof(WCHAR));
2184 if (!hmem) return E_OUTOFMEMORY;
2186 buf = GlobalLock(hmem);
2187 memcpy(buf, xml, lstrlenW(xml) * sizeof(WCHAR));
2188 GlobalUnlock(hmem);
2190 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2191 if (hr != S_OK)
2193 GlobalFree(hmem);
2194 return hr;
2197 hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
2198 if (hr != S_OK)
2200 IStream_Release(stream);
2201 return hr;
2204 hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
2205 if (hr == S_OK)
2206 hr = read_xml(reader, iface);
2208 IXmlReader_Release(reader);
2209 IStream_Release(stream);
2211 return hr;
2214 static const ITaskDefinitionVtbl TaskDefinition_vtbl =
2216 TaskDefinition_QueryInterface,
2217 TaskDefinition_AddRef,
2218 TaskDefinition_Release,
2219 TaskDefinition_GetTypeInfoCount,
2220 TaskDefinition_GetTypeInfo,
2221 TaskDefinition_GetIDsOfNames,
2222 TaskDefinition_Invoke,
2223 TaskDefinition_get_RegistrationInfo,
2224 TaskDefinition_put_RegistrationInfo,
2225 TaskDefinition_get_Triggers,
2226 TaskDefinition_put_Triggers,
2227 TaskDefinition_get_Settings,
2228 TaskDefinition_put_Settings,
2229 TaskDefinition_get_Data,
2230 TaskDefinition_put_Data,
2231 TaskDefinition_get_Principal,
2232 TaskDefinition_put_Principal,
2233 TaskDefinition_get_Actions,
2234 TaskDefinition_put_Actions,
2235 TaskDefinition_get_XmlText,
2236 TaskDefinition_put_XmlText
2239 HRESULT TaskDefinition_create(ITaskDefinition **obj)
2241 TaskDefinition *taskdef;
2243 taskdef = heap_alloc_zero(sizeof(*taskdef));
2244 if (!taskdef) return E_OUTOFMEMORY;
2246 taskdef->ITaskDefinition_iface.lpVtbl = &TaskDefinition_vtbl;
2247 taskdef->ref = 1;
2248 *obj = &taskdef->ITaskDefinition_iface;
2250 TRACE("created %p\n", *obj);
2252 return S_OK;
2255 typedef struct
2257 ITaskService ITaskService_iface;
2258 LONG ref;
2259 BOOL connected;
2260 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
2261 } TaskService;
2263 static inline TaskService *impl_from_ITaskService(ITaskService *iface)
2265 return CONTAINING_RECORD(iface, TaskService, ITaskService_iface);
2268 static ULONG WINAPI TaskService_AddRef(ITaskService *iface)
2270 TaskService *task_svc = impl_from_ITaskService(iface);
2271 return InterlockedIncrement(&task_svc->ref);
2274 static ULONG WINAPI TaskService_Release(ITaskService *iface)
2276 TaskService *task_svc = impl_from_ITaskService(iface);
2277 LONG ref = InterlockedDecrement(&task_svc->ref);
2279 if (!ref)
2281 TRACE("destroying %p\n", iface);
2282 heap_free(task_svc);
2285 return ref;
2288 static HRESULT WINAPI TaskService_QueryInterface(ITaskService *iface, REFIID riid, void **obj)
2290 if (!riid || !obj) return E_INVALIDARG;
2292 TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
2294 if (IsEqualGUID(riid, &IID_ITaskService) ||
2295 IsEqualGUID(riid, &IID_IDispatch) ||
2296 IsEqualGUID(riid, &IID_IUnknown))
2298 ITaskService_AddRef(iface);
2299 *obj = iface;
2300 return S_OK;
2303 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
2304 *obj = NULL;
2305 return E_NOINTERFACE;
2308 static HRESULT WINAPI TaskService_GetTypeInfoCount(ITaskService *iface, UINT *count)
2310 FIXME("%p,%p: stub\n", iface, count);
2311 return E_NOTIMPL;
2314 static HRESULT WINAPI TaskService_GetTypeInfo(ITaskService *iface, UINT index, LCID lcid, ITypeInfo **info)
2316 FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info);
2317 return E_NOTIMPL;
2320 static HRESULT WINAPI TaskService_GetIDsOfNames(ITaskService *iface, REFIID riid, LPOLESTR *names,
2321 UINT count, LCID lcid, DISPID *dispid)
2323 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
2324 return E_NOTIMPL;
2327 static HRESULT WINAPI TaskService_Invoke(ITaskService *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
2328 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
2330 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
2331 params, result, excepinfo, argerr);
2332 return E_NOTIMPL;
2335 static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITaskFolder **folder)
2337 TaskService *task_svc = impl_from_ITaskService(iface);
2339 TRACE("%p,%s,%p\n", iface, debugstr_w(path), folder);
2341 if (!folder) return E_POINTER;
2343 if (!task_svc->connected)
2344 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
2346 return TaskFolder_create(path, NULL, folder, FALSE);
2349 static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks)
2351 FIXME("%p,%x,%p: stub\n", iface, flags, tasks);
2352 return E_NOTIMPL;
2355 static HRESULT WINAPI TaskService_NewTask(ITaskService *iface, DWORD flags, ITaskDefinition **definition)
2357 TRACE("%p,%x,%p\n", iface, flags, definition);
2359 if (!definition) return E_POINTER;
2361 if (flags)
2362 FIXME("unsupported flags %x\n", flags);
2364 return TaskDefinition_create(definition);
2367 static inline BOOL is_variant_null(const VARIANT *var)
2369 return V_VT(var) == VT_EMPTY || V_VT(var) == VT_NULL ||
2370 (V_VT(var) == VT_BSTR && (V_BSTR(var) == NULL || !*V_BSTR(var)));
2373 static HRESULT WINAPI TaskService_Connect(ITaskService *iface, VARIANT server, VARIANT user, VARIANT domain, VARIANT password)
2375 TaskService *task_svc = impl_from_ITaskService(iface);
2376 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
2377 DWORD len;
2379 TRACE("%p,%s,%s,%s,%s\n", iface, debugstr_variant(&server), debugstr_variant(&user),
2380 debugstr_variant(&domain), debugstr_variant(&password));
2382 if (!is_variant_null(&user) || !is_variant_null(&domain) || !is_variant_null(&password))
2383 FIXME("user/domain/password are ignored\n");
2385 len = sizeof(comp_name)/sizeof(comp_name[0]);
2386 if (!GetComputerNameW(comp_name, &len))
2387 return HRESULT_FROM_WIN32(GetLastError());
2389 if (!is_variant_null(&server))
2391 const WCHAR *server_name;
2393 if (V_VT(&server) != VT_BSTR)
2395 FIXME("server variant type %d is not supported\n", V_VT(&server));
2396 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
2399 /* skip UNC prefix if any */
2400 server_name = V_BSTR(&server);
2401 if (server_name[0] == '\\' && server_name[1] == '\\')
2402 server_name += 2;
2404 if (strcmpiW(server_name, comp_name))
2406 FIXME("connection to remote server %s is not supported\n", debugstr_w(V_BSTR(&server)));
2407 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
2411 strcpyW(task_svc->comp_name, comp_name);
2412 task_svc->connected = TRUE;
2414 return S_OK;
2417 static HRESULT WINAPI TaskService_get_Connected(ITaskService *iface, VARIANT_BOOL *connected)
2419 TaskService *task_svc = impl_from_ITaskService(iface);
2421 TRACE("%p,%p\n", iface, connected);
2423 if (!connected) return E_POINTER;
2425 *connected = task_svc->connected ? VARIANT_TRUE : VARIANT_FALSE;
2427 return S_OK;
2430 static HRESULT WINAPI TaskService_get_TargetServer(ITaskService *iface, BSTR *server)
2432 TaskService *task_svc = impl_from_ITaskService(iface);
2434 TRACE("%p,%p\n", iface, server);
2436 if (!server) return E_POINTER;
2438 if (!task_svc->connected)
2439 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED);
2441 *server = SysAllocString(task_svc->comp_name);
2442 if (!*server) return E_OUTOFMEMORY;
2444 return S_OK;
2447 static HRESULT WINAPI TaskService_get_ConnectedUser(ITaskService *iface, BSTR *user)
2449 FIXME("%p,%p: stub\n", iface, user);
2450 return E_NOTIMPL;
2453 static HRESULT WINAPI TaskService_get_ConnectedDomain(ITaskService *iface, BSTR *domain)
2455 FIXME("%p,%p: stub\n", iface, domain);
2456 return E_NOTIMPL;
2459 static HRESULT WINAPI TaskService_get_HighestVersion(ITaskService *iface, DWORD *version)
2461 FIXME("%p,%p: stub\n", iface, version);
2462 return E_NOTIMPL;
2465 static const ITaskServiceVtbl TaskService_vtbl =
2467 TaskService_QueryInterface,
2468 TaskService_AddRef,
2469 TaskService_Release,
2470 TaskService_GetTypeInfoCount,
2471 TaskService_GetTypeInfo,
2472 TaskService_GetIDsOfNames,
2473 TaskService_Invoke,
2474 TaskService_GetFolder,
2475 TaskService_GetRunningTasks,
2476 TaskService_NewTask,
2477 TaskService_Connect,
2478 TaskService_get_Connected,
2479 TaskService_get_TargetServer,
2480 TaskService_get_ConnectedUser,
2481 TaskService_get_ConnectedDomain,
2482 TaskService_get_HighestVersion
2485 HRESULT TaskService_create(void **obj)
2487 TaskService *task_svc;
2489 task_svc = heap_alloc(sizeof(*task_svc));
2490 if (!task_svc) return E_OUTOFMEMORY;
2492 task_svc->ITaskService_iface.lpVtbl = &TaskService_vtbl;
2493 task_svc->ref = 1;
2494 task_svc->connected = FALSE;
2495 *obj = &task_svc->ITaskService_iface;
2497 TRACE("created %p\n", *obj);
2499 return S_OK;