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
31 #include "taskschd_private.h"
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(taskschd
);
40 IRegistrationInfo IRegistrationInfo_iface
;
42 WCHAR
*description
, *author
, *version
, *date
, *documentation
, *uri
, *source
;
45 static inline registration_info
*impl_from_IRegistrationInfo(IRegistrationInfo
*iface
)
47 return CONTAINING_RECORD(iface
, registration_info
, IRegistrationInfo_iface
);
50 static ULONG WINAPI
RegistrationInfo_AddRef(IRegistrationInfo
*iface
)
52 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
53 return InterlockedIncrement(®info
->ref
);
56 static ULONG WINAPI
RegistrationInfo_Release(IRegistrationInfo
*iface
)
58 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
59 LONG ref
= InterlockedDecrement(®info
->ref
);
63 TRACE("destroying %p\n", iface
);
64 heap_free(reginfo
->description
);
65 heap_free(reginfo
->author
);
66 heap_free(reginfo
->version
);
67 heap_free(reginfo
->date
);
68 heap_free(reginfo
->documentation
);
69 heap_free(reginfo
->uri
);
70 heap_free(reginfo
->source
);
77 static HRESULT WINAPI
RegistrationInfo_QueryInterface(IRegistrationInfo
*iface
, REFIID riid
, void **obj
)
79 if (!riid
|| !obj
) return E_INVALIDARG
;
81 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
83 if (IsEqualGUID(riid
, &IID_IRegistrationInfo
) ||
84 IsEqualGUID(riid
, &IID_IDispatch
) ||
85 IsEqualGUID(riid
, &IID_IUnknown
))
87 IRegistrationInfo_AddRef(iface
);
92 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
97 static HRESULT WINAPI
RegistrationInfo_GetTypeInfoCount(IRegistrationInfo
*iface
, UINT
*count
)
99 FIXME("%p,%p: stub\n", iface
, count
);
103 static HRESULT WINAPI
RegistrationInfo_GetTypeInfo(IRegistrationInfo
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
105 FIXME("%p,%u,%u,%p: stub\n", iface
, index
, lcid
, info
);
109 static HRESULT WINAPI
RegistrationInfo_GetIDsOfNames(IRegistrationInfo
*iface
, REFIID riid
, LPOLESTR
*names
,
110 UINT count
, LCID lcid
, DISPID
*dispid
)
112 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
116 static HRESULT WINAPI
RegistrationInfo_Invoke(IRegistrationInfo
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
,
117 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*argerr
)
119 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface
, dispid
, debugstr_guid(riid
), lcid
, flags
,
120 params
, result
, excepinfo
, argerr
);
124 static HRESULT WINAPI
RegistrationInfo_get_Description(IRegistrationInfo
*iface
, BSTR
*description
)
126 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
128 TRACE("%p,%p\n", iface
, description
);
130 if (!description
) return E_POINTER
;
132 *description
= SysAllocString(reginfo
->description
);
136 static HRESULT WINAPI
RegistrationInfo_put_Description(IRegistrationInfo
*iface
, BSTR description
)
138 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
140 TRACE("%p,%s\n", iface
, debugstr_w(description
));
142 if (!description
) return E_INVALIDARG
;
144 heap_free(reginfo
->description
);
145 reginfo
->description
= heap_strdupW(description
);
146 /* FIXME: update XML on the server side */
147 return reginfo
->description
? S_OK
: E_OUTOFMEMORY
;
150 static HRESULT WINAPI
RegistrationInfo_get_Author(IRegistrationInfo
*iface
, BSTR
*author
)
152 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
154 TRACE("%p,%p\n", iface
, author
);
156 if (!author
) return E_POINTER
;
158 *author
= SysAllocString(reginfo
->author
);
162 static HRESULT WINAPI
RegistrationInfo_put_Author(IRegistrationInfo
*iface
, BSTR author
)
164 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
166 TRACE("%p,%s\n", iface
, debugstr_w(author
));
168 if (!author
) return E_INVALIDARG
;
170 heap_free(reginfo
->author
);
171 reginfo
->author
= heap_strdupW(author
);
172 /* FIXME: update XML on the server side */
173 return reginfo
->author
? S_OK
: E_OUTOFMEMORY
;
176 static HRESULT WINAPI
RegistrationInfo_get_Version(IRegistrationInfo
*iface
, BSTR
*version
)
178 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
180 TRACE("%p,%p\n", iface
, version
);
182 if (!version
) return E_POINTER
;
184 *version
= SysAllocString(reginfo
->version
);
188 static HRESULT WINAPI
RegistrationInfo_put_Version(IRegistrationInfo
*iface
, BSTR version
)
190 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
192 TRACE("%p,%s\n", iface
, debugstr_w(version
));
194 if (!version
) return E_INVALIDARG
;
196 heap_free(reginfo
->version
);
197 reginfo
->version
= heap_strdupW(version
);
198 /* FIXME: update XML on the server side */
199 return reginfo
->version
? S_OK
: E_OUTOFMEMORY
;
202 static HRESULT WINAPI
RegistrationInfo_get_Date(IRegistrationInfo
*iface
, BSTR
*date
)
204 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
206 TRACE("%p,%p\n", iface
, date
);
208 if (!date
) return E_POINTER
;
210 *date
= SysAllocString(reginfo
->date
);
214 static HRESULT WINAPI
RegistrationInfo_put_Date(IRegistrationInfo
*iface
, BSTR date
)
216 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
218 TRACE("%p,%s\n", iface
, debugstr_w(date
));
220 if (!date
) return E_INVALIDARG
;
222 heap_free(reginfo
->date
);
223 reginfo
->date
= heap_strdupW(date
);
224 /* FIXME: update XML on the server side */
225 return reginfo
->date
? S_OK
: E_OUTOFMEMORY
;
228 static HRESULT WINAPI
RegistrationInfo_get_Documentation(IRegistrationInfo
*iface
, BSTR
*doc
)
230 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
232 TRACE("%p,%p\n", iface
, doc
);
234 if (!doc
) return E_POINTER
;
236 *doc
= SysAllocString(reginfo
->documentation
);
240 static HRESULT WINAPI
RegistrationInfo_put_Documentation(IRegistrationInfo
*iface
, BSTR doc
)
242 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
244 TRACE("%p,%s\n", iface
, debugstr_w(doc
));
246 if (!doc
) return E_INVALIDARG
;
248 heap_free(reginfo
->documentation
);
249 reginfo
->documentation
= heap_strdupW(doc
);
250 /* FIXME: update XML on the server side */
251 return reginfo
->documentation
? S_OK
: E_OUTOFMEMORY
;
254 static HRESULT WINAPI
RegistrationInfo_get_XmlText(IRegistrationInfo
*iface
, BSTR
*xml
)
256 FIXME("%p,%p: stub\n", iface
, xml
);
260 static HRESULT WINAPI
RegistrationInfo_put_XmlText(IRegistrationInfo
*iface
, BSTR xml
)
262 FIXME("%p,%s: stub\n", iface
, debugstr_w(xml
));
266 static HRESULT WINAPI
RegistrationInfo_get_URI(IRegistrationInfo
*iface
, BSTR
*uri
)
268 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
270 TRACE("%p,%p\n", iface
, uri
);
272 if (!uri
) return E_POINTER
;
274 *uri
= SysAllocString(reginfo
->uri
);
278 static HRESULT WINAPI
RegistrationInfo_put_URI(IRegistrationInfo
*iface
, BSTR uri
)
280 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
282 TRACE("%p,%s\n", iface
, debugstr_w(uri
));
284 if (!uri
) return E_INVALIDARG
;
286 heap_free(reginfo
->uri
);
287 reginfo
->uri
= heap_strdupW(uri
);
288 /* FIXME: update XML on the server side */
289 return reginfo
->uri
? S_OK
: E_OUTOFMEMORY
;
292 static HRESULT WINAPI
RegistrationInfo_get_SecurityDescriptor(IRegistrationInfo
*iface
, VARIANT
*sddl
)
294 FIXME("%p,%p: stub\n", iface
, sddl
);
298 static HRESULT WINAPI
RegistrationInfo_put_SecurityDescriptor(IRegistrationInfo
*iface
, VARIANT sddl
)
300 FIXME("%p,%s: stub\n", iface
, debugstr_variant(&sddl
));
304 static HRESULT WINAPI
RegistrationInfo_get_Source(IRegistrationInfo
*iface
, BSTR
*source
)
306 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
308 TRACE("%p,%p\n", iface
, source
);
310 if (!source
) return E_POINTER
;
312 *source
= SysAllocString(reginfo
->source
);
316 static HRESULT WINAPI
RegistrationInfo_put_Source(IRegistrationInfo
*iface
, BSTR source
)
318 registration_info
*reginfo
= impl_from_IRegistrationInfo(iface
);
320 TRACE("%p,%s\n", iface
, debugstr_w(source
));
322 if (!source
) return E_INVALIDARG
;
324 heap_free(reginfo
->source
);
325 reginfo
->source
= heap_strdupW(source
);
326 /* FIXME: update XML on the server side */
327 return reginfo
->source
? S_OK
: E_OUTOFMEMORY
;
330 static const IRegistrationInfoVtbl RegistrationInfo_vtbl
=
332 RegistrationInfo_QueryInterface
,
333 RegistrationInfo_AddRef
,
334 RegistrationInfo_Release
,
335 RegistrationInfo_GetTypeInfoCount
,
336 RegistrationInfo_GetTypeInfo
,
337 RegistrationInfo_GetIDsOfNames
,
338 RegistrationInfo_Invoke
,
339 RegistrationInfo_get_Description
,
340 RegistrationInfo_put_Description
,
341 RegistrationInfo_get_Author
,
342 RegistrationInfo_put_Author
,
343 RegistrationInfo_get_Version
,
344 RegistrationInfo_put_Version
,
345 RegistrationInfo_get_Date
,
346 RegistrationInfo_put_Date
,
347 RegistrationInfo_get_Documentation
,
348 RegistrationInfo_put_Documentation
,
349 RegistrationInfo_get_XmlText
,
350 RegistrationInfo_put_XmlText
,
351 RegistrationInfo_get_URI
,
352 RegistrationInfo_put_URI
,
353 RegistrationInfo_get_SecurityDescriptor
,
354 RegistrationInfo_put_SecurityDescriptor
,
355 RegistrationInfo_get_Source
,
356 RegistrationInfo_put_Source
359 static HRESULT
RegistrationInfo_create(IRegistrationInfo
**obj
)
361 registration_info
*reginfo
;
363 reginfo
= heap_alloc_zero(sizeof(*reginfo
));
364 if (!reginfo
) return E_OUTOFMEMORY
;
366 reginfo
->IRegistrationInfo_iface
.lpVtbl
= &RegistrationInfo_vtbl
;
368 *obj
= ®info
->IRegistrationInfo_iface
;
370 TRACE("created %p\n", *obj
);
377 ITaskSettings ITaskSettings_iface
;
379 WCHAR
*restart_interval
;
380 WCHAR
*execution_time_limit
;
381 WCHAR
*delete_expired_task_after
;
384 TASK_INSTANCES_POLICY policy
;
385 TASK_COMPATIBILITY compatibility
;
386 BOOL allow_on_demand_start
;
387 BOOL stop_if_going_on_batteries
;
388 BOOL disallow_start_if_on_batteries
;
389 BOOL allow_hard_terminate
;
390 BOOL start_when_available
;
391 BOOL run_only_if_network_available
;
394 BOOL run_only_if_idle
;
398 static inline TaskSettings
*impl_from_ITaskSettings(ITaskSettings
*iface
)
400 return CONTAINING_RECORD(iface
, TaskSettings
, ITaskSettings_iface
);
403 static ULONG WINAPI
TaskSettings_AddRef(ITaskSettings
*iface
)
405 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
406 return InterlockedIncrement(&taskset
->ref
);
409 static ULONG WINAPI
TaskSettings_Release(ITaskSettings
*iface
)
411 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
412 LONG ref
= InterlockedDecrement(&taskset
->ref
);
416 TRACE("destroying %p\n", iface
);
417 heap_free(taskset
->restart_interval
);
418 heap_free(taskset
->execution_time_limit
);
419 heap_free(taskset
->delete_expired_task_after
);
426 static HRESULT WINAPI
TaskSettings_QueryInterface(ITaskSettings
*iface
, REFIID riid
, void **obj
)
428 if (!riid
|| !obj
) return E_INVALIDARG
;
430 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
432 if (IsEqualGUID(riid
, &IID_ITaskSettings
) ||
433 IsEqualGUID(riid
, &IID_IDispatch
) ||
434 IsEqualGUID(riid
, &IID_IUnknown
))
436 ITaskSettings_AddRef(iface
);
441 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
443 return E_NOINTERFACE
;
446 static HRESULT WINAPI
TaskSettings_GetTypeInfoCount(ITaskSettings
*iface
, UINT
*count
)
448 FIXME("%p,%p: stub\n", iface
, count
);
452 static HRESULT WINAPI
TaskSettings_GetTypeInfo(ITaskSettings
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
454 FIXME("%p,%u,%u,%p: stub\n", iface
, index
, lcid
, info
);
458 static HRESULT WINAPI
TaskSettings_GetIDsOfNames(ITaskSettings
*iface
, REFIID riid
, LPOLESTR
*names
,
459 UINT count
, LCID lcid
, DISPID
*dispid
)
461 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
465 static HRESULT WINAPI
TaskSettings_Invoke(ITaskSettings
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
,
466 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*argerr
)
468 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface
, dispid
, debugstr_guid(riid
), lcid
, flags
,
469 params
, result
, excepinfo
, argerr
);
473 static HRESULT WINAPI
TaskSettings_get_AllowDemandStart(ITaskSettings
*iface
, VARIANT_BOOL
*allow
)
475 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
477 TRACE("%p,%p\n", iface
, allow
);
479 if (!allow
) return E_POINTER
;
481 *allow
= taskset
->allow_on_demand_start
? VARIANT_TRUE
: VARIANT_FALSE
;
486 static HRESULT WINAPI
TaskSettings_put_AllowDemandStart(ITaskSettings
*iface
, VARIANT_BOOL allow
)
488 FIXME("%p,%d: stub\n", iface
, allow
);
492 static HRESULT WINAPI
TaskSettings_get_RestartInterval(ITaskSettings
*iface
, BSTR
*interval
)
494 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
496 TRACE("%p,%p\n", iface
, interval
);
498 if (!interval
) return E_POINTER
;
500 if (!taskset
->restart_interval
)
506 *interval
= SysAllocString(taskset
->restart_interval
);
507 if (!*interval
) return E_OUTOFMEMORY
;
512 static HRESULT WINAPI
TaskSettings_put_RestartInterval(ITaskSettings
*iface
, BSTR interval
)
514 TRACE("%p,%s\n", iface
, debugstr_w(interval
));
518 static HRESULT WINAPI
TaskSettings_get_RestartCount(ITaskSettings
*iface
, INT
*count
)
520 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
522 TRACE("%p,%p\n", iface
, count
);
524 if (!count
) return E_POINTER
;
526 *count
= taskset
->restart_count
;
531 static HRESULT WINAPI
TaskSettings_put_RestartCount(ITaskSettings
*iface
, INT count
)
533 FIXME("%p,%d: stub\n", iface
, count
);
537 static HRESULT WINAPI
TaskSettings_get_MultipleInstances(ITaskSettings
*iface
, TASK_INSTANCES_POLICY
*policy
)
539 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
541 TRACE("%p,%p\n", iface
, policy
);
543 if (!policy
) return E_POINTER
;
545 *policy
= taskset
->policy
;
550 static HRESULT WINAPI
TaskSettings_put_MultipleInstances(ITaskSettings
*iface
, TASK_INSTANCES_POLICY policy
)
552 FIXME("%p,%d: stub\n", iface
, policy
);
556 static HRESULT WINAPI
TaskSettings_get_StopIfGoingOnBatteries(ITaskSettings
*iface
, VARIANT_BOOL
*stop
)
558 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
560 TRACE("%p,%p\n", iface
, stop
);
562 if (!stop
) return E_POINTER
;
564 *stop
= taskset
->stop_if_going_on_batteries
? VARIANT_TRUE
: VARIANT_FALSE
;
569 static HRESULT WINAPI
TaskSettings_put_StopIfGoingOnBatteries(ITaskSettings
*iface
, VARIANT_BOOL stop
)
571 FIXME("%p,%d: stub\n", iface
, stop
);
575 static HRESULT WINAPI
TaskSettings_get_DisallowStartIfOnBatteries(ITaskSettings
*iface
, VARIANT_BOOL
*disallow
)
577 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
579 TRACE("%p,%p\n", iface
, disallow
);
581 if (!disallow
) return E_POINTER
;
583 *disallow
= taskset
->disallow_start_if_on_batteries
? VARIANT_TRUE
: VARIANT_FALSE
;
588 static HRESULT WINAPI
TaskSettings_put_DisallowStartIfOnBatteries(ITaskSettings
*iface
, VARIANT_BOOL disallow
)
590 FIXME("%p,%d: stub\n", iface
, disallow
);
594 static HRESULT WINAPI
TaskSettings_get_AllowHardTerminate(ITaskSettings
*iface
, VARIANT_BOOL
*allow
)
596 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
598 TRACE("%p,%p\n", iface
, allow
);
600 if (!allow
) return E_POINTER
;
602 *allow
= taskset
->allow_hard_terminate
? VARIANT_TRUE
: VARIANT_FALSE
;
607 static HRESULT WINAPI
TaskSettings_put_AllowHardTerminate(ITaskSettings
*iface
, VARIANT_BOOL allow
)
609 FIXME("%p,%d: stub\n", iface
, allow
);
613 static HRESULT WINAPI
TaskSettings_get_StartWhenAvailable(ITaskSettings
*iface
, VARIANT_BOOL
*start
)
615 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
617 TRACE("%p,%p\n", iface
, start
);
619 if (!start
) return E_POINTER
;
621 *start
= taskset
->start_when_available
? VARIANT_TRUE
: VARIANT_FALSE
;
626 static HRESULT WINAPI
TaskSettings_put_StartWhenAvailable(ITaskSettings
*iface
, VARIANT_BOOL start
)
628 FIXME("%p,%d: stub\n", iface
, start
);
632 static HRESULT WINAPI
TaskSettings_get_XmlText(ITaskSettings
*iface
, BSTR
*xml
)
634 FIXME("%p,%p: stub\n", iface
, xml
);
638 static HRESULT WINAPI
TaskSettings_put_XmlText(ITaskSettings
*iface
, BSTR xml
)
640 FIXME("%p,%s: stub\n", iface
, debugstr_w(xml
));
644 static HRESULT WINAPI
TaskSettings_get_RunOnlyIfNetworkAvailable(ITaskSettings
*iface
, VARIANT_BOOL
*run
)
646 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
648 TRACE("%p,%p\n", iface
, run
);
650 if (!run
) return E_POINTER
;
652 *run
= taskset
->run_only_if_network_available
? VARIANT_TRUE
: VARIANT_FALSE
;
657 static HRESULT WINAPI
TaskSettings_put_RunOnlyIfNetworkAvailable(ITaskSettings
*iface
, VARIANT_BOOL run
)
659 FIXME("%p,%d: stub\n", iface
, run
);
663 static HRESULT WINAPI
TaskSettings_get_ExecutionTimeLimit(ITaskSettings
*iface
, BSTR
*limit
)
665 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
667 TRACE("%p,%p\n", iface
, limit
);
669 if (!limit
) return E_POINTER
;
671 if (!taskset
->execution_time_limit
)
677 *limit
= SysAllocString(taskset
->execution_time_limit
);
678 if (!*limit
) return E_OUTOFMEMORY
;
683 static HRESULT WINAPI
TaskSettings_put_ExecutionTimeLimit(ITaskSettings
*iface
, BSTR limit
)
685 TRACE("%p,%s\n", iface
, debugstr_w(limit
));
689 static HRESULT WINAPI
TaskSettings_get_Enabled(ITaskSettings
*iface
, VARIANT_BOOL
*enabled
)
691 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
693 TRACE("%p,%p\n", iface
, enabled
);
695 if (!enabled
) return E_POINTER
;
697 *enabled
= taskset
->enabled
? VARIANT_TRUE
: VARIANT_FALSE
;
702 static HRESULT WINAPI
TaskSettings_put_Enabled(ITaskSettings
*iface
, VARIANT_BOOL enabled
)
704 FIXME("%p,%d: stub\n", iface
, enabled
);
708 static HRESULT WINAPI
TaskSettings_get_DeleteExpiredTaskAfter(ITaskSettings
*iface
, BSTR
*delay
)
710 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
712 TRACE("%p,%p\n", iface
, delay
);
714 if (!delay
) return E_POINTER
;
716 if (!taskset
->delete_expired_task_after
)
722 *delay
= SysAllocString(taskset
->delete_expired_task_after
);
723 if (!*delay
) return E_OUTOFMEMORY
;
728 static HRESULT WINAPI
TaskSettings_put_DeleteExpiredTaskAfter(ITaskSettings
*iface
, BSTR delay
)
730 TRACE("%p,%s\n", iface
, debugstr_w(delay
));
734 static HRESULT WINAPI
TaskSettings_get_Priority(ITaskSettings
*iface
, INT
*priority
)
736 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
738 TRACE("%p,%p\n", iface
, priority
);
740 if (!priority
) return E_POINTER
;
742 *priority
= taskset
->priority
;
747 static HRESULT WINAPI
TaskSettings_put_Priority(ITaskSettings
*iface
, INT priority
)
749 FIXME("%p,%d: stub\n", iface
, priority
);
753 static HRESULT WINAPI
TaskSettings_get_Compatibility(ITaskSettings
*iface
, TASK_COMPATIBILITY
*level
)
755 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
757 TRACE("%p,%p\n", iface
, level
);
759 if (!level
) return E_POINTER
;
761 *level
= taskset
->compatibility
;
766 static HRESULT WINAPI
TaskSettings_put_Compatibility(ITaskSettings
*iface
, TASK_COMPATIBILITY level
)
768 FIXME("%p,%d: stub\n", iface
, level
);
772 static HRESULT WINAPI
TaskSettings_get_Hidden(ITaskSettings
*iface
, VARIANT_BOOL
*hidden
)
774 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
776 TRACE("%p,%p\n", iface
, hidden
);
778 if (!hidden
) return E_POINTER
;
780 *hidden
= taskset
->hidden
? VARIANT_TRUE
: VARIANT_FALSE
;
785 static HRESULT WINAPI
TaskSettings_put_Hidden(ITaskSettings
*iface
, VARIANT_BOOL hidden
)
787 FIXME("%p,%d: stub\n", iface
, hidden
);
791 static HRESULT WINAPI
TaskSettings_get_IdleSettings(ITaskSettings
*iface
, IIdleSettings
**settings
)
793 FIXME("%p,%p: stub\n", iface
, settings
);
797 static HRESULT WINAPI
TaskSettings_put_IdleSettings(ITaskSettings
*iface
, IIdleSettings
*settings
)
799 FIXME("%p,%p: stub\n", iface
, settings
);
803 static HRESULT WINAPI
TaskSettings_get_RunOnlyIfIdle(ITaskSettings
*iface
, VARIANT_BOOL
*run
)
805 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
807 TRACE("%p,%p\n", iface
, run
);
809 if (!run
) return E_POINTER
;
811 *run
= taskset
->run_only_if_idle
? VARIANT_TRUE
: VARIANT_FALSE
;
816 static HRESULT WINAPI
TaskSettings_put_RunOnlyIfIdle(ITaskSettings
*iface
, VARIANT_BOOL run
)
818 FIXME("%p,%d: stub\n", iface
, run
);
822 static HRESULT WINAPI
TaskSettings_get_WakeToRun(ITaskSettings
*iface
, VARIANT_BOOL
*wake
)
824 TaskSettings
*taskset
= impl_from_ITaskSettings(iface
);
826 TRACE("%p,%p\n", iface
, wake
);
828 if (!wake
) return E_POINTER
;
830 *wake
= taskset
->wake_to_run
? VARIANT_TRUE
: VARIANT_FALSE
;
835 static HRESULT WINAPI
TaskSettings_put_WakeToRun(ITaskSettings
*iface
, VARIANT_BOOL wake
)
837 FIXME("%p,%d: stub\n", iface
, wake
);
841 static HRESULT WINAPI
TaskSettings_get_NetworkSettings(ITaskSettings
*iface
, INetworkSettings
**settings
)
843 FIXME("%p,%p: stub\n", iface
, settings
);
847 static HRESULT WINAPI
TaskSettings_put_NetworkSettings(ITaskSettings
*iface
, INetworkSettings
*settings
)
849 FIXME("%p,%p: stub\n", iface
, settings
);
853 static const ITaskSettingsVtbl TaskSettings_vtbl
=
855 TaskSettings_QueryInterface
,
857 TaskSettings_Release
,
858 TaskSettings_GetTypeInfoCount
,
859 TaskSettings_GetTypeInfo
,
860 TaskSettings_GetIDsOfNames
,
862 TaskSettings_get_AllowDemandStart
,
863 TaskSettings_put_AllowDemandStart
,
864 TaskSettings_get_RestartInterval
,
865 TaskSettings_put_RestartInterval
,
866 TaskSettings_get_RestartCount
,
867 TaskSettings_put_RestartCount
,
868 TaskSettings_get_MultipleInstances
,
869 TaskSettings_put_MultipleInstances
,
870 TaskSettings_get_StopIfGoingOnBatteries
,
871 TaskSettings_put_StopIfGoingOnBatteries
,
872 TaskSettings_get_DisallowStartIfOnBatteries
,
873 TaskSettings_put_DisallowStartIfOnBatteries
,
874 TaskSettings_get_AllowHardTerminate
,
875 TaskSettings_put_AllowHardTerminate
,
876 TaskSettings_get_StartWhenAvailable
,
877 TaskSettings_put_StartWhenAvailable
,
878 TaskSettings_get_XmlText
,
879 TaskSettings_put_XmlText
,
880 TaskSettings_get_RunOnlyIfNetworkAvailable
,
881 TaskSettings_put_RunOnlyIfNetworkAvailable
,
882 TaskSettings_get_ExecutionTimeLimit
,
883 TaskSettings_put_ExecutionTimeLimit
,
884 TaskSettings_get_Enabled
,
885 TaskSettings_put_Enabled
,
886 TaskSettings_get_DeleteExpiredTaskAfter
,
887 TaskSettings_put_DeleteExpiredTaskAfter
,
888 TaskSettings_get_Priority
,
889 TaskSettings_put_Priority
,
890 TaskSettings_get_Compatibility
,
891 TaskSettings_put_Compatibility
,
892 TaskSettings_get_Hidden
,
893 TaskSettings_put_Hidden
,
894 TaskSettings_get_IdleSettings
,
895 TaskSettings_put_IdleSettings
,
896 TaskSettings_get_RunOnlyIfIdle
,
897 TaskSettings_put_RunOnlyIfIdle
,
898 TaskSettings_get_WakeToRun
,
899 TaskSettings_put_WakeToRun
,
900 TaskSettings_get_NetworkSettings
,
901 TaskSettings_put_NetworkSettings
904 static HRESULT
TaskSettings_create(ITaskSettings
**obj
)
906 static const WCHAR exec_time_limit
[] = { 'P','T','7','2','H',0 };
907 TaskSettings
*taskset
;
909 taskset
= heap_alloc(sizeof(*taskset
));
910 if (!taskset
) return E_OUTOFMEMORY
;
912 taskset
->ITaskSettings_iface
.lpVtbl
= &TaskSettings_vtbl
;
914 /* set the defaults */
915 taskset
->restart_interval
= NULL
;
916 taskset
->execution_time_limit
= heap_strdupW(exec_time_limit
);
917 taskset
->delete_expired_task_after
= NULL
;
918 taskset
->restart_count
= 0;
919 taskset
->priority
= 7;
920 taskset
->policy
= TASK_INSTANCES_IGNORE_NEW
;
921 taskset
->compatibility
= TASK_COMPATIBILITY_V2
;
922 taskset
->allow_on_demand_start
= TRUE
;
923 taskset
->stop_if_going_on_batteries
= TRUE
;
924 taskset
->disallow_start_if_on_batteries
= TRUE
;
925 taskset
->allow_hard_terminate
= TRUE
;
926 taskset
->start_when_available
= FALSE
;
927 taskset
->run_only_if_network_available
= FALSE
;
928 taskset
->enabled
= TRUE
;
929 taskset
->hidden
= FALSE
;
930 taskset
->run_only_if_idle
= FALSE
;
931 taskset
->wake_to_run
= FALSE
;
933 *obj
= &taskset
->ITaskSettings_iface
;
935 TRACE("created %p\n", *obj
);
942 ITaskDefinition ITaskDefinition_iface
;
944 IRegistrationInfo
*reginfo
;
945 ITaskSettings
*taskset
;
946 ITriggerCollection
*triggers
;
947 IPrincipal
*principal
;
948 IActionCollection
*actions
;
951 static inline TaskDefinition
*impl_from_ITaskDefinition(ITaskDefinition
*iface
)
953 return CONTAINING_RECORD(iface
, TaskDefinition
, ITaskDefinition_iface
);
956 static ULONG WINAPI
TaskDefinition_AddRef(ITaskDefinition
*iface
)
958 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
959 return InterlockedIncrement(&taskdef
->ref
);
962 static ULONG WINAPI
TaskDefinition_Release(ITaskDefinition
*iface
)
964 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
965 LONG ref
= InterlockedDecrement(&taskdef
->ref
);
969 TRACE("destroying %p\n", iface
);
971 if (taskdef
->reginfo
)
972 IRegistrationInfo_Release(taskdef
->reginfo
);
973 if (taskdef
->taskset
)
974 ITaskSettings_Release(taskdef
->taskset
);
975 if (taskdef
->triggers
)
976 ITriggerCollection_Release(taskdef
->triggers
);
977 if (taskdef
->principal
)
978 IPrincipal_Release(taskdef
->principal
);
979 if (taskdef
->actions
)
980 IActionCollection_Release(taskdef
->actions
);
988 static HRESULT WINAPI
TaskDefinition_QueryInterface(ITaskDefinition
*iface
, REFIID riid
, void **obj
)
990 if (!riid
|| !obj
) return E_INVALIDARG
;
992 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
994 if (IsEqualGUID(riid
, &IID_ITaskDefinition
) ||
995 IsEqualGUID(riid
, &IID_IDispatch
) ||
996 IsEqualGUID(riid
, &IID_IUnknown
))
998 ITaskDefinition_AddRef(iface
);
1003 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
1005 return E_NOINTERFACE
;
1008 static HRESULT WINAPI
TaskDefinition_GetTypeInfoCount(ITaskDefinition
*iface
, UINT
*count
)
1010 FIXME("%p,%p: stub\n", iface
, count
);
1014 static HRESULT WINAPI
TaskDefinition_GetTypeInfo(ITaskDefinition
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
1016 FIXME("%p,%u,%u,%p: stub\n", iface
, index
, lcid
, info
);
1020 static HRESULT WINAPI
TaskDefinition_GetIDsOfNames(ITaskDefinition
*iface
, REFIID riid
, LPOLESTR
*names
,
1021 UINT count
, LCID lcid
, DISPID
*dispid
)
1023 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
1027 static HRESULT WINAPI
TaskDefinition_Invoke(ITaskDefinition
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
,
1028 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*argerr
)
1030 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface
, dispid
, debugstr_guid(riid
), lcid
, flags
,
1031 params
, result
, excepinfo
, argerr
);
1035 static HRESULT WINAPI
TaskDefinition_get_RegistrationInfo(ITaskDefinition
*iface
, IRegistrationInfo
**info
)
1037 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
1040 TRACE("%p,%p\n", iface
, info
);
1042 if (!info
) return E_POINTER
;
1044 if (!taskdef
->reginfo
)
1046 hr
= RegistrationInfo_create(&taskdef
->reginfo
);
1047 if (hr
!= S_OK
) return hr
;
1050 IRegistrationInfo_AddRef(taskdef
->reginfo
);
1051 *info
= taskdef
->reginfo
;
1056 static HRESULT WINAPI
TaskDefinition_put_RegistrationInfo(ITaskDefinition
*iface
, IRegistrationInfo
*info
)
1058 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
1060 TRACE("%p,%p\n", iface
, info
);
1062 if (!info
) return E_POINTER
;
1064 if (taskdef
->reginfo
)
1065 IRegistrationInfo_Release(taskdef
->reginfo
);
1067 IRegistrationInfo_AddRef(info
);
1068 taskdef
->reginfo
= info
;
1073 static HRESULT WINAPI
TaskDefinition_get_Triggers(ITaskDefinition
*iface
, ITriggerCollection
**triggers
)
1075 FIXME("%p,%p: stub\n", iface
, triggers
);
1079 static HRESULT WINAPI
TaskDefinition_put_Triggers(ITaskDefinition
*iface
, ITriggerCollection
*triggers
)
1081 FIXME("%p,%p: stub\n", iface
, triggers
);
1085 static HRESULT WINAPI
TaskDefinition_get_Settings(ITaskDefinition
*iface
, ITaskSettings
**settings
)
1087 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
1090 TRACE("%p,%p\n", iface
, settings
);
1092 if (!settings
) return E_POINTER
;
1094 if (!taskdef
->taskset
)
1096 hr
= TaskSettings_create(&taskdef
->taskset
);
1097 if (hr
!= S_OK
) return hr
;
1100 ITaskSettings_AddRef(taskdef
->taskset
);
1101 *settings
= taskdef
->taskset
;
1106 static HRESULT WINAPI
TaskDefinition_put_Settings(ITaskDefinition
*iface
, ITaskSettings
*settings
)
1108 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
1110 TRACE("%p,%p\n", iface
, settings
);
1112 if (!settings
) return E_POINTER
;
1114 if (taskdef
->taskset
)
1115 ITaskSettings_Release(taskdef
->taskset
);
1117 ITaskSettings_AddRef(settings
);
1118 taskdef
->taskset
= settings
;
1123 static HRESULT WINAPI
TaskDefinition_get_Data(ITaskDefinition
*iface
, BSTR
*data
)
1125 FIXME("%p,%p: stub\n", iface
, data
);
1129 static HRESULT WINAPI
TaskDefinition_put_Data(ITaskDefinition
*iface
, BSTR data
)
1131 FIXME("%p,%p: stub\n", iface
, data
);
1135 static HRESULT WINAPI
TaskDefinition_get_Principal(ITaskDefinition
*iface
, IPrincipal
**principal
)
1137 FIXME("%p,%p: stub\n", iface
, principal
);
1141 static HRESULT WINAPI
TaskDefinition_put_Principal(ITaskDefinition
*iface
, IPrincipal
*principal
)
1143 FIXME("%p,%p: stub\n", iface
, principal
);
1147 static HRESULT WINAPI
TaskDefinition_get_Actions(ITaskDefinition
*iface
, IActionCollection
**actions
)
1149 FIXME("%p,%p: stub\n", iface
, actions
);
1153 static HRESULT WINAPI
TaskDefinition_put_Actions(ITaskDefinition
*iface
, IActionCollection
*actions
)
1155 FIXME("%p,%p: stub\n", iface
, actions
);
1159 static const WCHAR Task
[] = {'T','a','s','k',0};
1160 static const WCHAR version
[] = {'v','e','r','s','i','o','n',0};
1161 static const WCHAR v1_0
[] = {'1','.','0',0};
1162 static const WCHAR v1_1
[] = {'1','.','1',0};
1163 static const WCHAR v1_2
[] = {'1','.','2',0};
1164 static const WCHAR v1_3
[] = {'1','.','3',0};
1165 static const WCHAR xmlns
[] = {'x','m','l','n','s',0};
1166 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};
1167 static const WCHAR RegistrationInfo
[] = {'R','e','g','i','s','t','r','a','t','i','o','n','I','n','f','o',0};
1168 static const WCHAR Author
[] = {'A','u','t','h','o','r',0};
1169 static const WCHAR Description
[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
1170 static const WCHAR Source
[] = {'S','o','u','r','c','e',0};
1171 static const WCHAR Date
[] = {'D','a','t','e',0};
1172 static const WCHAR Version
[] = {'V','e','r','s','i','o','n',0};
1173 static const WCHAR Documentation
[] = {'D','o','c','u','m','e','n','t','a','t','i','o','n',0};
1174 static const WCHAR URI
[] = {'U','R','I',0};
1175 static const WCHAR SecurityDescriptor
[] = {'S','e','c','u','r','i','t','y','D','e','s','c','r','i','p','t','o','r',0};
1176 static const WCHAR Settings
[] = {'S','e','t','t','i','n','g','s',0};
1177 static const WCHAR Triggers
[] = {'T','r','i','g','g','e','r','s',0};
1178 static const WCHAR Principals
[] = {'P','r','i','n','c','i','p','a','l','s',0};
1179 static const WCHAR Principal
[] = {'P','r','i','n','c','i','p','a','l',0};
1180 static const WCHAR id
[] = {'i','d',0};
1181 static const WCHAR UserId
[] = {'U','s','e','r','I','d',0};
1182 static const WCHAR LogonType
[] = {'L','o','g','o','n','T','y','p','e',0};
1183 static const WCHAR GroupId
[] = {'G','r','o','u','p','I','d',0};
1184 static const WCHAR DisplayName
[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
1185 static const WCHAR HighestAvailable
[] = {'H','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
1186 static const WCHAR Password
[] = {'P','a','s','s','w','o','r','d',0};
1187 static const WCHAR S4U
[] = {'S','4','U',0};
1188 static const WCHAR InteractiveToken
[] = {'I','n','t','e','r','a','c','t','i','v','e','T','o','k','e','n',0};
1189 static const WCHAR RunLevel
[] = {'R','u','n','L','e','v','e','l',0};
1190 static const WCHAR LeastPrivilege
[] = {'L','e','a','s','t','P','r','i','v','i','l','e','g','e',0};
1191 static const WCHAR Actions
[] = {'A','c','t','i','o','n','s',0};
1192 static const WCHAR Exec
[] = {'E','x','e','c',0};
1193 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};
1194 static const WCHAR IgnoreNew
[] = {'I','g','n','o','r','e','N','e','w',0};
1195 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};
1196 static const WCHAR AllowStartOnDemand
[] = {'A','l','l','o','w','S','t','a','r','t','O','n','D','e','m','a','n','d',0};
1197 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};
1198 static const WCHAR AllowHardTerminate
[] = {'A','l','l','o','w','H','a','r','d','T','e','r','m','i','n','a','t','e',0};
1199 static const WCHAR StartWhenAvailable
[] = {'S','t','a','r','t','W','h','e','n','A','v','a','i','l','a','b','l','e',0};
1200 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};
1201 static const WCHAR Enabled
[] = {'E','n','a','b','l','e','d',0};
1202 static const WCHAR Hidden
[] = {'H','i','d','d','e','n',0};
1203 static const WCHAR RunOnlyIfIdle
[] = {'R','u','n','O','n','l','y','I','f','I','d','l','e',0};
1204 static const WCHAR WakeToRun
[] = {'W','a','k','e','T','o','R','u','n',0};
1205 static const WCHAR ExecutionTimeLimit
[] = {'E','x','e','c','u','t','i','o','n','T','i','m','e','L','i','m','i','t',0};
1206 static const WCHAR Priority
[] = {'P','r','i','o','r','i','t','y',0};
1207 static const WCHAR IdleSettings
[] = {'I','d','l','e','S','e','t','t','i','n','g','s',0};
1209 static int xml_indent
;
1211 static inline void push_indent(void)
1216 static inline void pop_indent(void)
1221 static inline HRESULT
write_stringW(IStream
*stream
, const WCHAR
*str
)
1223 return IStream_Write(stream
, str
, lstrlenW(str
) * sizeof(WCHAR
), NULL
);
1226 static void write_indent(IStream
*stream
)
1228 static const WCHAR spacesW
[] = {' ',' ',0};
1230 for (i
= 0; i
< xml_indent
; i
+= 2)
1231 write_stringW(stream
, spacesW
);
1234 static const WCHAR start_element
[] = {'<',0};
1235 static const WCHAR start_end_element
[] = {'<','/',0};
1236 static const WCHAR close_element
[] = {'>',0};
1237 static const WCHAR end_empty_element
[] = {'/','>',0};
1238 static const WCHAR eol
[] = {'\n',0};
1239 static const WCHAR spaceW
[] = {' ',0};
1240 static const WCHAR equalW
[] = {'=',0};
1241 static const WCHAR quoteW
[] = {'"',0};
1243 static inline HRESULT
write_empty_element(IStream
*stream
, const WCHAR
*name
)
1245 write_indent(stream
);
1246 write_stringW(stream
, start_element
);
1247 write_stringW(stream
, name
);
1248 write_stringW(stream
, end_empty_element
);
1249 return write_stringW(stream
, eol
);
1252 static inline HRESULT
write_element(IStream
*stream
, const WCHAR
*name
)
1254 write_indent(stream
);
1255 write_stringW(stream
, start_element
);
1256 write_stringW(stream
, name
);
1257 write_stringW(stream
, close_element
);
1258 return write_stringW(stream
, eol
);
1261 static inline HRESULT
write_element_end(IStream
*stream
, const WCHAR
*name
)
1263 write_indent(stream
);
1264 write_stringW(stream
, start_end_element
);
1265 write_stringW(stream
, name
);
1266 write_stringW(stream
, close_element
);
1267 return write_stringW(stream
, eol
);
1270 static inline HRESULT
write_text_value(IStream
*stream
, const WCHAR
*name
, const WCHAR
*value
)
1272 write_indent(stream
);
1273 write_stringW(stream
, start_element
);
1274 write_stringW(stream
, name
);
1275 write_stringW(stream
, close_element
);
1276 write_stringW(stream
, value
);
1277 write_stringW(stream
, start_end_element
);
1278 write_stringW(stream
, name
);
1279 write_stringW(stream
, close_element
);
1280 return write_stringW(stream
, eol
);
1283 static HRESULT
write_task_attributes(IStream
*stream
, ITaskDefinition
*taskdef
)
1286 ITaskSettings
*taskset
;
1287 TASK_COMPATIBILITY level
;
1288 const WCHAR
*compatibility
;
1290 hr
= ITaskDefinition_get_Settings(taskdef
, &taskset
);
1291 if (hr
!= S_OK
) return hr
;
1293 hr
= ITaskSettings_get_Compatibility(taskset
, &level
);
1294 if (hr
!= S_OK
) level
= TASK_COMPATIBILITY_V2_1
;
1296 ITaskSettings_Release(taskset
);
1300 case TASK_COMPATIBILITY_AT
:
1301 compatibility
= v1_0
;
1303 case TASK_COMPATIBILITY_V1
:
1304 compatibility
= v1_1
;
1306 case TASK_COMPATIBILITY_V2
:
1307 compatibility
= v1_2
;
1310 compatibility
= v1_3
;
1314 write_stringW(stream
, start_element
);
1315 write_stringW(stream
, Task
);
1316 write_stringW(stream
, spaceW
);
1317 write_stringW(stream
, version
);
1318 write_stringW(stream
, equalW
);
1319 write_stringW(stream
, quoteW
);
1320 write_stringW(stream
, compatibility
);
1321 write_stringW(stream
, quoteW
);
1322 write_stringW(stream
, spaceW
);
1323 write_stringW(stream
, xmlns
);
1324 write_stringW(stream
, equalW
);
1325 write_stringW(stream
, quoteW
);
1326 write_stringW(stream
, task_ns
);
1327 write_stringW(stream
, quoteW
);
1328 write_stringW(stream
, close_element
);
1329 return write_stringW(stream
, eol
);
1332 static HRESULT
write_registration_info(IStream
*stream
, IRegistrationInfo
*reginfo
)
1339 return write_empty_element(stream
, RegistrationInfo
);
1341 hr
= write_element(stream
, RegistrationInfo
);
1342 if (hr
!= S_OK
) return hr
;
1346 hr
= IRegistrationInfo_get_Source(reginfo
, &bstr
);
1347 if (hr
== S_OK
&& bstr
)
1349 hr
= write_text_value(stream
, Source
, bstr
);
1350 SysFreeString(bstr
);
1351 if (hr
!= S_OK
) return hr
;
1353 hr
= IRegistrationInfo_get_Date(reginfo
, &bstr
);
1354 if (hr
== S_OK
&& bstr
)
1356 hr
= write_text_value(stream
, Date
, bstr
);
1357 SysFreeString(bstr
);
1358 if (hr
!= S_OK
) return hr
;
1360 hr
= IRegistrationInfo_get_Author(reginfo
, &bstr
);
1361 if (hr
== S_OK
&& bstr
)
1363 hr
= write_text_value(stream
, Author
, bstr
);
1364 SysFreeString(bstr
);
1365 if (hr
!= S_OK
) return hr
;
1367 hr
= IRegistrationInfo_get_Version(reginfo
, &bstr
);
1368 if (hr
== S_OK
&& bstr
)
1370 hr
= write_text_value(stream
, Version
, bstr
);
1371 SysFreeString(bstr
);
1372 if (hr
!= S_OK
) return hr
;
1374 hr
= IRegistrationInfo_get_Description(reginfo
, &bstr
);
1375 if (hr
== S_OK
&& bstr
)
1377 hr
= write_text_value(stream
, Description
, bstr
);
1378 SysFreeString(bstr
);
1379 if (hr
!= S_OK
) return hr
;
1381 hr
= IRegistrationInfo_get_Documentation(reginfo
, &bstr
);
1382 if (hr
== S_OK
&& bstr
)
1384 hr
= write_text_value(stream
, Documentation
, bstr
);
1385 SysFreeString(bstr
);
1386 if (hr
!= S_OK
) return hr
;
1388 hr
= IRegistrationInfo_get_URI(reginfo
, &bstr
);
1389 if (hr
== S_OK
&& bstr
)
1391 hr
= write_text_value(stream
, URI
, bstr
);
1392 SysFreeString(bstr
);
1393 if (hr
!= S_OK
) return hr
;
1395 hr
= IRegistrationInfo_get_SecurityDescriptor(reginfo
, &var
);
1398 if (V_VT(&var
) == VT_BSTR
)
1400 hr
= write_text_value(stream
, SecurityDescriptor
, V_BSTR(&var
));
1402 if (hr
!= S_OK
) return hr
;
1405 FIXME("SecurityInfo variant type %d is not supported\n", V_VT(&var
));
1410 return write_element_end(stream
, RegistrationInfo
);
1413 static HRESULT
write_principal(IStream
*stream
, IPrincipal
*principal
)
1417 TASK_LOGON_TYPE logon
;
1418 TASK_RUNLEVEL_TYPE level
;
1421 return write_empty_element(stream
, Principals
);
1423 hr
= write_element(stream
, Principals
);
1424 if (hr
!= S_OK
) return hr
;
1428 hr
= IPrincipal_get_Id(principal
, &bstr
);
1431 write_indent(stream
);
1432 write_stringW(stream
, start_element
);
1433 write_stringW(stream
, Principal
);
1434 write_stringW(stream
, spaceW
);
1435 write_stringW(stream
, id
);
1436 write_stringW(stream
, equalW
);
1437 write_stringW(stream
, quoteW
);
1438 write_stringW(stream
, bstr
);
1439 write_stringW(stream
, quoteW
);
1440 write_stringW(stream
, close_element
);
1441 write_stringW(stream
, eol
);
1442 SysFreeString(bstr
);
1445 write_element(stream
, Principal
);
1449 hr
= IPrincipal_get_GroupId(principal
, &bstr
);
1452 hr
= write_text_value(stream
, GroupId
, bstr
);
1453 SysFreeString(bstr
);
1454 if (hr
!= S_OK
) return hr
;
1456 hr
= IPrincipal_get_DisplayName(principal
, &bstr
);
1459 hr
= write_text_value(stream
, DisplayName
, bstr
);
1460 SysFreeString(bstr
);
1461 if (hr
!= S_OK
) return hr
;
1463 hr
= IPrincipal_get_UserId(principal
, &bstr
);
1464 if (hr
== S_OK
&& lstrlenW(bstr
))
1466 hr
= write_text_value(stream
, UserId
, bstr
);
1467 SysFreeString(bstr
);
1468 if (hr
!= S_OK
) return hr
;
1470 hr
= IPrincipal_get_RunLevel(principal
, &level
);
1473 const WCHAR
*level_str
= NULL
;
1477 case TASK_RUNLEVEL_HIGHEST
:
1478 level_str
= HighestAvailable
;
1480 case TASK_RUNLEVEL_LUA
:
1481 level_str
= LeastPrivilege
;
1484 FIXME("Principal run level %d\n", level
);
1490 hr
= write_text_value(stream
, RunLevel
, level_str
);
1491 if (hr
!= S_OK
) return hr
;
1494 hr
= IPrincipal_get_LogonType(principal
, &logon
);
1497 const WCHAR
*logon_str
= NULL
;
1501 case TASK_LOGON_PASSWORD
:
1502 logon_str
= Password
;
1504 case TASK_LOGON_S4U
:
1507 case TASK_LOGON_INTERACTIVE_TOKEN
:
1508 logon_str
= InteractiveToken
;
1511 FIXME("Principal logon type %d\n", logon
);
1517 hr
= write_text_value(stream
, LogonType
, logon_str
);
1518 if (hr
!= S_OK
) return hr
;
1523 write_element_end(stream
, Principal
);
1526 return write_element_end(stream
, Principals
);
1529 static HRESULT
write_settings(IStream
*stream
, ITaskSettings
*settings
)
1532 return write_empty_element(stream
, Settings
);
1538 static HRESULT
write_triggers(IStream
*stream
, ITriggerCollection
*triggers
)
1541 return write_empty_element(stream
, Triggers
);
1547 static HRESULT
write_actions(IStream
*stream
, IActionCollection
*actions
)
1551 write_element(stream
, Actions
);
1553 write_empty_element(stream
, Exec
);
1555 return write_element_end(stream
, Actions
);
1562 static HRESULT WINAPI
TaskDefinition_get_XmlText(ITaskDefinition
*iface
, BSTR
*xml
)
1564 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
1570 TRACE("%p,%p\n", iface
, xml
);
1572 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
1573 if (!hmem
) return E_OUTOFMEMORY
;
1575 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
1582 hr
= write_task_attributes(stream
, &taskdef
->ITaskDefinition_iface
);
1583 if (hr
!= S_OK
) goto failed
;
1587 hr
= write_registration_info(stream
, taskdef
->reginfo
);
1588 if (hr
!= S_OK
) goto failed
;
1590 hr
= write_triggers(stream
, taskdef
->triggers
);
1591 if (hr
!= S_OK
) goto failed
;
1593 hr
= write_principal(stream
, taskdef
->principal
);
1594 if (hr
!= S_OK
) goto failed
;
1596 hr
= write_settings(stream
, taskdef
->taskset
);
1597 if (hr
!= S_OK
) goto failed
;
1599 hr
= write_actions(stream
, taskdef
->actions
);
1600 if (hr
!= S_OK
) goto failed
;
1604 write_element_end(stream
, Task
);
1605 IStream_Write(stream
, "\0\0", 2, NULL
);
1607 p
= GlobalLock(hmem
);
1608 *xml
= SysAllocString(p
);
1611 IStream_Release(stream
);
1613 return *xml
? S_OK
: E_OUTOFMEMORY
;
1616 IStream_Release(stream
);
1620 static HRESULT
read_text_value(IXmlReader
*reader
, WCHAR
**value
)
1625 while (IXmlReader_Read(reader
, &type
) == S_OK
)
1629 case XmlNodeType_Text
:
1630 hr
= IXmlReader_GetValue(reader
, (const WCHAR
**)value
, NULL
);
1631 if (hr
!= S_OK
) return hr
;
1632 TRACE("%s\n", debugstr_w(*value
));
1635 case XmlNodeType_Whitespace
:
1636 case XmlNodeType_Comment
:
1640 FIXME("unexpected node type %d\n", type
);
1648 static HRESULT
read_variantbool_value(IXmlReader
*reader
, VARIANT_BOOL
*vbool
)
1650 static const WCHAR trueW
[] = {'t','r','u','e',0};
1651 static const WCHAR falseW
[] = {'f','a','l','s','e',0};
1655 hr
= read_text_value(reader
, &value
);
1656 if (hr
!= S_OK
) return hr
;
1658 if (!lstrcmpW(value
, trueW
))
1659 *vbool
= VARIANT_TRUE
;
1660 else if (!lstrcmpW(value
, falseW
))
1661 *vbool
= VARIANT_FALSE
;
1664 WARN("unexpected bool value %s\n", debugstr_w(value
));
1665 return SCHED_E_INVALIDVALUE
;
1671 static HRESULT
read_int_value(IXmlReader
*reader
, int *int_val
)
1676 hr
= read_text_value(reader
, &value
);
1677 if (hr
!= S_OK
) return hr
;
1679 *int_val
= strtolW(value
, NULL
, 10);
1684 static HRESULT
read_triggers(IXmlReader
*reader
, ITaskDefinition
*taskdef
)
1690 static HRESULT
read_principal_attributes(IXmlReader
*reader
, IPrincipal
*principal
)
1696 hr
= IXmlReader_MoveToFirstAttribute(reader
);
1700 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
1701 if (hr
!= S_OK
) break;
1703 hr
= IXmlReader_GetValue(reader
, &value
, NULL
);
1704 if (hr
!= S_OK
) break;
1706 TRACE("%s=%s\n", debugstr_w(name
), debugstr_w(value
));
1708 if (!lstrcmpW(name
, id
))
1709 IPrincipal_put_Id(principal
, (BSTR
)value
);
1711 FIXME("unhandled Principal attribute %s\n", debugstr_w(name
));
1713 hr
= IXmlReader_MoveToNextAttribute(reader
);
1719 static HRESULT
read_principal(IXmlReader
*reader
, IPrincipal
*principal
)
1726 if (IXmlReader_IsEmptyElement(reader
))
1728 TRACE("Principal is empty\n");
1732 read_principal_attributes(reader
, principal
);
1734 while (IXmlReader_Read(reader
, &type
) == S_OK
)
1738 case XmlNodeType_EndElement
:
1739 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
1740 if (hr
!= S_OK
) return hr
;
1742 TRACE("/%s\n", debugstr_w(name
));
1744 if (!lstrcmpW(name
, Principal
))
1749 case XmlNodeType_Element
:
1750 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
1751 if (hr
!= S_OK
) return hr
;
1753 TRACE("Element: %s\n", debugstr_w(name
));
1755 if (!lstrcmpW(name
, UserId
))
1757 hr
= read_text_value(reader
, &value
);
1759 IPrincipal_put_UserId(principal
, value
);
1761 else if (!lstrcmpW(name
, LogonType
))
1763 hr
= read_text_value(reader
, &value
);
1766 TASK_LOGON_TYPE logon
= TASK_LOGON_NONE
;
1768 if (!lstrcmpW(value
, InteractiveToken
))
1769 logon
= TASK_LOGON_INTERACTIVE_TOKEN
;
1771 FIXME("unhandled LogonType %s\n", debugstr_w(value
));
1773 IPrincipal_put_LogonType(principal
, logon
);
1776 else if (!lstrcmpW(name
, RunLevel
))
1778 hr
= read_text_value(reader
, &value
);
1781 TASK_RUNLEVEL_TYPE level
= TASK_RUNLEVEL_LUA
;
1783 if (!lstrcmpW(value
, LeastPrivilege
))
1784 level
= TASK_RUNLEVEL_LUA
;
1786 FIXME("unhandled RunLevel %s\n", debugstr_w(value
));
1788 IPrincipal_put_RunLevel(principal
, level
);
1792 FIXME("unhandled Principal element %s\n", debugstr_w(name
));
1796 case XmlNodeType_Whitespace
:
1797 case XmlNodeType_Comment
:
1801 FIXME("unhandled Principal node type %d\n", type
);
1806 WARN("Principal was not terminated\n");
1810 static HRESULT
read_principals(IXmlReader
*reader
, ITaskDefinition
*taskdef
)
1816 if (IXmlReader_IsEmptyElement(reader
))
1818 TRACE("Principals is empty\n");
1822 while (IXmlReader_Read(reader
, &type
) == S_OK
)
1826 case XmlNodeType_EndElement
:
1827 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
1828 if (hr
!= S_OK
) return hr
;
1830 TRACE("/%s\n", debugstr_w(name
));
1832 if (!lstrcmpW(name
, Principals
))
1837 case XmlNodeType_Element
:
1838 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
1839 if (hr
!= S_OK
) return hr
;
1841 TRACE("Element: %s\n", debugstr_w(name
));
1843 if (!lstrcmpW(name
, Principal
))
1845 IPrincipal
*principal
;
1847 hr
= ITaskDefinition_get_Principal(taskdef
, &principal
);
1848 if (hr
!= S_OK
) return hr
;
1849 hr
= read_principal(reader
, principal
);
1850 IPrincipal_Release(principal
);
1853 FIXME("unhandled Principals element %s\n", debugstr_w(name
));
1857 case XmlNodeType_Whitespace
:
1858 case XmlNodeType_Comment
:
1862 FIXME("unhandled Principals node type %d\n", type
);
1867 WARN("Principals was not terminated\n");
1871 static HRESULT
read_actions(IXmlReader
*reader
, ITaskDefinition
*taskdef
)
1877 static HRESULT
read_idle_settings(IXmlReader
*reader
, ITaskSettings
*taskset
)
1883 static HRESULT
read_settings(IXmlReader
*reader
, ITaskSettings
*taskset
)
1889 VARIANT_BOOL bool_val
;
1892 if (IXmlReader_IsEmptyElement(reader
))
1894 TRACE("Settings is empty\n");
1898 while (IXmlReader_Read(reader
, &type
) == S_OK
)
1902 case XmlNodeType_EndElement
:
1903 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
1904 if (hr
!= S_OK
) return hr
;
1906 TRACE("/%s\n", debugstr_w(name
));
1908 if (!lstrcmpW(name
, Settings
))
1913 case XmlNodeType_Element
:
1914 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
1915 if (hr
!= S_OK
) return hr
;
1917 TRACE("Element: %s\n", debugstr_w(name
));
1919 if (!lstrcmpW(name
, MultipleInstancesPolicy
))
1921 hr
= read_text_value(reader
, &value
);
1924 int_val
= TASK_INSTANCES_IGNORE_NEW
;
1926 if (!lstrcmpW(value
, IgnoreNew
))
1927 int_val
= TASK_INSTANCES_IGNORE_NEW
;
1929 FIXME("unhandled MultipleInstancesPolicy %s\n", debugstr_w(value
));
1931 ITaskSettings_put_MultipleInstances(taskset
, int_val
);
1934 else if (!lstrcmpW(name
, DisallowStartIfOnBatteries
))
1936 hr
= read_variantbool_value(reader
, &bool_val
);
1937 if (hr
!= S_OK
) return hr
;
1938 ITaskSettings_put_DisallowStartIfOnBatteries(taskset
, bool_val
);
1940 else if (!lstrcmpW(name
, AllowStartOnDemand
))
1942 hr
= read_variantbool_value(reader
, &bool_val
);
1943 if (hr
!= S_OK
) return hr
;
1944 ITaskSettings_put_AllowDemandStart(taskset
, bool_val
);
1946 else if (!lstrcmpW(name
, StopIfGoingOnBatteries
))
1948 hr
= read_variantbool_value(reader
, &bool_val
);
1949 if (hr
!= S_OK
) return hr
;
1950 ITaskSettings_put_StopIfGoingOnBatteries(taskset
, bool_val
);
1952 else if (!lstrcmpW(name
, AllowHardTerminate
))
1954 hr
= read_variantbool_value(reader
, &bool_val
);
1955 if (hr
!= S_OK
) return hr
;
1956 ITaskSettings_put_AllowHardTerminate(taskset
, bool_val
);
1958 else if (!lstrcmpW(name
, StartWhenAvailable
))
1960 hr
= read_variantbool_value(reader
, &bool_val
);
1961 if (hr
!= S_OK
) return hr
;
1962 ITaskSettings_put_StartWhenAvailable(taskset
, bool_val
);
1964 else if (!lstrcmpW(name
, RunOnlyIfNetworkAvailable
))
1966 hr
= read_variantbool_value(reader
, &bool_val
);
1967 if (hr
!= S_OK
) return hr
;
1968 ITaskSettings_put_RunOnlyIfNetworkAvailable(taskset
, bool_val
);
1970 else if (!lstrcmpW(name
, Enabled
))
1972 hr
= read_variantbool_value(reader
, &bool_val
);
1973 if (hr
!= S_OK
) return hr
;
1974 ITaskSettings_put_Enabled(taskset
, bool_val
);
1976 else if (!lstrcmpW(name
, Hidden
))
1978 hr
= read_variantbool_value(reader
, &bool_val
);
1979 if (hr
!= S_OK
) return hr
;
1980 ITaskSettings_put_Hidden(taskset
, bool_val
);
1982 else if (!lstrcmpW(name
, RunOnlyIfIdle
))
1984 hr
= read_variantbool_value(reader
, &bool_val
);
1985 if (hr
!= S_OK
) return hr
;
1986 ITaskSettings_put_RunOnlyIfIdle(taskset
, bool_val
);
1988 else if (!lstrcmpW(name
, WakeToRun
))
1990 hr
= read_variantbool_value(reader
, &bool_val
);
1991 if (hr
!= S_OK
) return hr
;
1992 ITaskSettings_put_WakeToRun(taskset
, bool_val
);
1994 else if (!lstrcmpW(name
, ExecutionTimeLimit
))
1996 hr
= read_text_value(reader
, &value
);
1998 ITaskSettings_put_ExecutionTimeLimit(taskset
, value
);
2000 else if (!lstrcmpW(name
, Priority
))
2002 hr
= read_int_value(reader
, &int_val
);
2004 ITaskSettings_put_Priority(taskset
, int_val
);
2006 else if (!lstrcmpW(name
, IdleSettings
))
2008 hr
= read_idle_settings(reader
, taskset
);
2009 if (hr
!= S_OK
) return hr
;
2012 FIXME("unhandled Settings element %s\n", debugstr_w(name
));
2016 case XmlNodeType_Whitespace
:
2017 case XmlNodeType_Comment
:
2021 FIXME("unhandled Settings node type %d\n", type
);
2026 WARN("Settings was not terminated\n");
2027 return SCHED_E_MALFORMEDXML
;
2030 static HRESULT
read_registration_info(IXmlReader
*reader
, IRegistrationInfo
*info
)
2037 if (IXmlReader_IsEmptyElement(reader
))
2039 TRACE("RegistrationInfo is empty\n");
2043 while (IXmlReader_Read(reader
, &type
) == S_OK
)
2047 case XmlNodeType_EndElement
:
2048 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2049 if (hr
!= S_OK
) return hr
;
2051 TRACE("/%s\n", debugstr_w(name
));
2053 if (!lstrcmpW(name
, RegistrationInfo
))
2058 case XmlNodeType_Element
:
2059 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2060 if (hr
!= S_OK
) return hr
;
2062 TRACE("Element: %s\n", debugstr_w(name
));
2064 if (!lstrcmpW(name
, Author
))
2066 hr
= read_text_value(reader
, &value
);
2068 IRegistrationInfo_put_Author(info
, value
);
2070 else if (!lstrcmpW(name
, Description
))
2072 hr
= read_text_value(reader
, &value
);
2074 IRegistrationInfo_put_Description(info
, value
);
2077 FIXME("unhandled RegistrationInfo element %s\n", debugstr_w(name
));
2081 case XmlNodeType_Whitespace
:
2082 case XmlNodeType_Comment
:
2086 FIXME("unhandled RegistrationInfo node type %d\n", type
);
2091 WARN("RegistrationInfo was not terminated\n");
2092 return SCHED_E_MALFORMEDXML
;
2095 static HRESULT
read_task_attributes(IXmlReader
*reader
, ITaskDefinition
*taskdef
)
2098 ITaskSettings
*taskset
;
2101 BOOL xmlns_ok
= FALSE
;
2105 hr
= ITaskDefinition_get_Settings(taskdef
, &taskset
);
2106 if (hr
!= S_OK
) return hr
;
2108 hr
= IXmlReader_MoveToFirstAttribute(reader
);
2112 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2113 if (hr
!= S_OK
) break;
2115 hr
= IXmlReader_GetValue(reader
, &value
, NULL
);
2116 if (hr
!= S_OK
) break;
2118 TRACE("%s=%s\n", debugstr_w(name
), debugstr_w(value
));
2120 if (!lstrcmpW(name
, version
))
2122 TASK_COMPATIBILITY compatibility
= TASK_COMPATIBILITY_V2
;
2124 if (!lstrcmpW(value
, v1_0
))
2125 compatibility
= TASK_COMPATIBILITY_AT
;
2126 else if (!lstrcmpW(value
, v1_1
))
2127 compatibility
= TASK_COMPATIBILITY_V1
;
2128 else if (!lstrcmpW(value
, v1_2
))
2129 compatibility
= TASK_COMPATIBILITY_V2
;
2130 else if (!lstrcmpW(value
, v1_3
))
2131 compatibility
= TASK_COMPATIBILITY_V2_1
;
2133 FIXME("unknown version %s\n", debugstr_w(value
));
2135 ITaskSettings_put_Compatibility(taskset
, compatibility
);
2137 else if (!lstrcmpW(name
, xmlns
))
2139 if (lstrcmpW(value
, task_ns
))
2141 FIXME("unknown namespace %s\n", debugstr_w(value
));
2147 FIXME("unhandled Task attribute %s\n", debugstr_w(name
));
2149 hr
= IXmlReader_MoveToNextAttribute(reader
);
2152 ITaskSettings_Release(taskset
);
2153 return xmlns_ok
? S_OK
: SCHED_E_NAMESPACE
;
2156 static HRESULT
read_task(IXmlReader
*reader
, ITaskDefinition
*taskdef
)
2162 if (IXmlReader_IsEmptyElement(reader
))
2164 TRACE("Task is empty\n");
2168 while (IXmlReader_Read(reader
, &type
) == S_OK
)
2172 case XmlNodeType_EndElement
:
2173 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2174 if (hr
!= S_OK
) return hr
;
2176 TRACE("/%s\n", debugstr_w(name
));
2178 if (!lstrcmpW(name
, Task
))
2183 case XmlNodeType_Element
:
2184 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2185 if (hr
!= S_OK
) return hr
;
2187 TRACE("Element: %s\n", debugstr_w(name
));
2189 if (!lstrcmpW(name
, RegistrationInfo
))
2191 IRegistrationInfo
*info
;
2193 hr
= ITaskDefinition_get_RegistrationInfo(taskdef
, &info
);
2194 if (hr
!= S_OK
) return hr
;
2195 hr
= read_registration_info(reader
, info
);
2196 IRegistrationInfo_Release(info
);
2198 else if (!lstrcmpW(name
, Settings
))
2200 ITaskSettings
*taskset
;
2202 hr
= ITaskDefinition_get_Settings(taskdef
, &taskset
);
2203 if (hr
!= S_OK
) return hr
;
2204 hr
= read_settings(reader
, taskset
);
2205 ITaskSettings_Release(taskset
);
2207 else if (!lstrcmpW(name
, Triggers
))
2208 hr
= read_triggers(reader
, taskdef
);
2209 else if (!lstrcmpW(name
, Principals
))
2210 hr
= read_principals(reader
, taskdef
);
2211 else if (!lstrcmpW(name
, Actions
))
2212 hr
= read_actions(reader
, taskdef
);
2214 FIXME("unhandled Task element %s\n", debugstr_w(name
));
2216 if (hr
!= S_OK
) return hr
;
2219 case XmlNodeType_Comment
:
2220 case XmlNodeType_Whitespace
:
2224 FIXME("unhandled Task node type %d\n", type
);
2229 WARN("Task was not terminated\n");
2230 return SCHED_E_MALFORMEDXML
;
2233 static HRESULT
read_xml(IXmlReader
*reader
, ITaskDefinition
*taskdef
)
2239 while (IXmlReader_Read(reader
, &type
) == S_OK
)
2243 case XmlNodeType_XmlDeclaration
:
2244 TRACE("XmlDeclaration\n");
2247 case XmlNodeType_Element
:
2248 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2249 if (hr
!= S_OK
) return hr
;
2251 TRACE("Element: %s\n", debugstr_w(name
));
2253 if (!lstrcmpW(name
, Task
))
2255 hr
= read_task_attributes(reader
, taskdef
);
2256 if (hr
!= S_OK
) return hr
;
2258 return read_task(reader
, taskdef
);
2261 FIXME("unhandled XML element %s\n", debugstr_w(name
));
2265 case XmlNodeType_Comment
:
2266 case XmlNodeType_Whitespace
:
2270 FIXME("unhandled XML node type %d\n", type
);
2275 WARN("Task definition was not found\n");
2276 return SCHED_E_MALFORMEDXML
;
2279 static HRESULT WINAPI
TaskDefinition_put_XmlText(ITaskDefinition
*iface
, BSTR xml
)
2281 TaskDefinition
*taskdef
= impl_from_ITaskDefinition(iface
);
2288 TRACE("%p,%s\n", iface
, debugstr_w(xml
));
2290 if (!xml
) return E_INVALIDARG
;
2292 hmem
= GlobalAlloc(0, lstrlenW(xml
) * sizeof(WCHAR
));
2293 if (!hmem
) return E_OUTOFMEMORY
;
2295 buf
= GlobalLock(hmem
);
2296 memcpy(buf
, xml
, lstrlenW(xml
) * sizeof(WCHAR
));
2299 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
2306 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2309 IStream_Release(stream
);
2313 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
2316 if (taskdef
->reginfo
)
2318 IRegistrationInfo_Release(taskdef
->reginfo
);
2319 taskdef
->reginfo
= NULL
;
2321 if (taskdef
->taskset
)
2323 ITaskSettings_Release(taskdef
->taskset
);
2324 taskdef
->taskset
= NULL
;
2326 if (taskdef
->triggers
)
2328 ITriggerCollection_Release(taskdef
->triggers
);
2329 taskdef
->triggers
= NULL
;
2331 if (taskdef
->principal
)
2333 IPrincipal_Release(taskdef
->principal
);
2334 taskdef
->principal
= NULL
;
2336 if (taskdef
->actions
)
2338 IActionCollection_Release(taskdef
->actions
);
2339 taskdef
->actions
= NULL
;
2342 hr
= read_xml(reader
, iface
);
2345 IXmlReader_Release(reader
);
2346 IStream_Release(stream
);
2351 static const ITaskDefinitionVtbl TaskDefinition_vtbl
=
2353 TaskDefinition_QueryInterface
,
2354 TaskDefinition_AddRef
,
2355 TaskDefinition_Release
,
2356 TaskDefinition_GetTypeInfoCount
,
2357 TaskDefinition_GetTypeInfo
,
2358 TaskDefinition_GetIDsOfNames
,
2359 TaskDefinition_Invoke
,
2360 TaskDefinition_get_RegistrationInfo
,
2361 TaskDefinition_put_RegistrationInfo
,
2362 TaskDefinition_get_Triggers
,
2363 TaskDefinition_put_Triggers
,
2364 TaskDefinition_get_Settings
,
2365 TaskDefinition_put_Settings
,
2366 TaskDefinition_get_Data
,
2367 TaskDefinition_put_Data
,
2368 TaskDefinition_get_Principal
,
2369 TaskDefinition_put_Principal
,
2370 TaskDefinition_get_Actions
,
2371 TaskDefinition_put_Actions
,
2372 TaskDefinition_get_XmlText
,
2373 TaskDefinition_put_XmlText
2376 HRESULT
TaskDefinition_create(ITaskDefinition
**obj
)
2378 TaskDefinition
*taskdef
;
2380 taskdef
= heap_alloc_zero(sizeof(*taskdef
));
2381 if (!taskdef
) return E_OUTOFMEMORY
;
2383 taskdef
->ITaskDefinition_iface
.lpVtbl
= &TaskDefinition_vtbl
;
2385 *obj
= &taskdef
->ITaskDefinition_iface
;
2387 TRACE("created %p\n", *obj
);
2394 ITaskService ITaskService_iface
;
2398 WCHAR comp_name
[MAX_COMPUTERNAME_LENGTH
+ 1];
2401 static inline TaskService
*impl_from_ITaskService(ITaskService
*iface
)
2403 return CONTAINING_RECORD(iface
, TaskService
, ITaskService_iface
);
2406 static ULONG WINAPI
TaskService_AddRef(ITaskService
*iface
)
2408 TaskService
*task_svc
= impl_from_ITaskService(iface
);
2409 return InterlockedIncrement(&task_svc
->ref
);
2412 static ULONG WINAPI
TaskService_Release(ITaskService
*iface
)
2414 TaskService
*task_svc
= impl_from_ITaskService(iface
);
2415 LONG ref
= InterlockedDecrement(&task_svc
->ref
);
2419 TRACE("destroying %p\n", iface
);
2420 heap_free(task_svc
);
2426 static HRESULT WINAPI
TaskService_QueryInterface(ITaskService
*iface
, REFIID riid
, void **obj
)
2428 if (!riid
|| !obj
) return E_INVALIDARG
;
2430 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
2432 if (IsEqualGUID(riid
, &IID_ITaskService
) ||
2433 IsEqualGUID(riid
, &IID_IDispatch
) ||
2434 IsEqualGUID(riid
, &IID_IUnknown
))
2436 ITaskService_AddRef(iface
);
2441 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
2443 return E_NOINTERFACE
;
2446 static HRESULT WINAPI
TaskService_GetTypeInfoCount(ITaskService
*iface
, UINT
*count
)
2448 FIXME("%p,%p: stub\n", iface
, count
);
2452 static HRESULT WINAPI
TaskService_GetTypeInfo(ITaskService
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
2454 FIXME("%p,%u,%u,%p: stub\n", iface
, index
, lcid
, info
);
2458 static HRESULT WINAPI
TaskService_GetIDsOfNames(ITaskService
*iface
, REFIID riid
, LPOLESTR
*names
,
2459 UINT count
, LCID lcid
, DISPID
*dispid
)
2461 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
2465 static HRESULT WINAPI
TaskService_Invoke(ITaskService
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
,
2466 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*argerr
)
2468 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface
, dispid
, debugstr_guid(riid
), lcid
, flags
,
2469 params
, result
, excepinfo
, argerr
);
2473 static HRESULT WINAPI
TaskService_GetFolder(ITaskService
*iface
, BSTR path
, ITaskFolder
**folder
)
2475 TaskService
*task_svc
= impl_from_ITaskService(iface
);
2477 TRACE("%p,%s,%p\n", iface
, debugstr_w(path
), folder
);
2479 if (!folder
) return E_POINTER
;
2481 if (!task_svc
->connected
)
2482 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED
);
2484 return TaskFolder_create(path
, NULL
, folder
, FALSE
);
2487 static HRESULT WINAPI
TaskService_GetRunningTasks(ITaskService
*iface
, LONG flags
, IRunningTaskCollection
**tasks
)
2489 FIXME("%p,%x,%p: stub\n", iface
, flags
, tasks
);
2493 static HRESULT WINAPI
TaskService_NewTask(ITaskService
*iface
, DWORD flags
, ITaskDefinition
**definition
)
2495 TRACE("%p,%x,%p\n", iface
, flags
, definition
);
2497 if (!definition
) return E_POINTER
;
2500 FIXME("unsupported flags %x\n", flags
);
2502 return TaskDefinition_create(definition
);
2505 static inline BOOL
is_variant_null(const VARIANT
*var
)
2507 return V_VT(var
) == VT_EMPTY
|| V_VT(var
) == VT_NULL
||
2508 (V_VT(var
) == VT_BSTR
&& (V_BSTR(var
) == NULL
|| !*V_BSTR(var
)));
2511 static HRESULT
start_schedsvc(void)
2513 static const WCHAR scheduleW
[] = { 'S','c','h','e','d','u','l','e',0 };
2514 SC_HANDLE scm
, service
;
2515 SERVICE_STATUS_PROCESS status
;
2516 ULONGLONG start_time
;
2517 HRESULT hr
= SCHED_E_SERVICE_NOT_RUNNING
;
2519 TRACE("Trying to start %s service\n", debugstr_w(scheduleW
));
2521 scm
= OpenSCManagerW(NULL
, NULL
, 0);
2522 if (!scm
) return SCHED_E_SERVICE_NOT_INSTALLED
;
2524 service
= OpenServiceW(scm
, scheduleW
, SERVICE_START
| SERVICE_QUERY_STATUS
);
2527 if (StartServiceW(service
, 0, NULL
) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING
)
2529 start_time
= GetTickCount64();
2534 if (!QueryServiceStatusEx(service
, SC_STATUS_PROCESS_INFO
, (BYTE
*)&status
, sizeof(status
), &dummy
))
2536 WARN("failed to query scheduler status (%u)\n", GetLastError());
2540 if (status
.dwCurrentState
== SERVICE_RUNNING
)
2546 if (GetTickCount64() - start_time
> 30000) break;
2549 } while (status
.dwCurrentState
== SERVICE_START_PENDING
);
2551 if (status
.dwCurrentState
!= SERVICE_RUNNING
)
2552 WARN("scheduler failed to start %u\n", status
.dwCurrentState
);
2555 WARN("failed to start scheduler service (%u)\n", GetLastError());
2557 CloseServiceHandle(service
);
2560 WARN("failed to open scheduler service (%u)\n", GetLastError());
2562 CloseServiceHandle(scm
);
2566 static HRESULT WINAPI
TaskService_Connect(ITaskService
*iface
, VARIANT server
, VARIANT user
, VARIANT domain
, VARIANT password
)
2568 static WCHAR ncalrpc
[] = { 'n','c','a','l','r','p','c',0 };
2569 TaskService
*task_svc
= impl_from_ITaskService(iface
);
2570 WCHAR comp_name
[MAX_COMPUTERNAME_LENGTH
+ 1];
2573 RPC_WSTR binding_str
;
2574 extern handle_t rpc_handle
;
2576 TRACE("%p,%s,%s,%s,%s\n", iface
, debugstr_variant(&server
), debugstr_variant(&user
),
2577 debugstr_variant(&domain
), debugstr_variant(&password
));
2579 if (!is_variant_null(&user
) || !is_variant_null(&domain
) || !is_variant_null(&password
))
2580 FIXME("user/domain/password are ignored\n");
2582 len
= sizeof(comp_name
)/sizeof(comp_name
[0]);
2583 if (!GetComputerNameW(comp_name
, &len
))
2584 return HRESULT_FROM_WIN32(GetLastError());
2586 if (!is_variant_null(&server
))
2588 const WCHAR
*server_name
;
2590 if (V_VT(&server
) != VT_BSTR
)
2592 FIXME("server variant type %d is not supported\n", V_VT(&server
));
2593 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH
);
2596 /* skip UNC prefix if any */
2597 server_name
= V_BSTR(&server
);
2598 if (server_name
[0] == '\\' && server_name
[1] == '\\')
2601 if (strcmpiW(server_name
, comp_name
))
2603 FIXME("connection to remote server %s is not supported\n", debugstr_w(V_BSTR(&server
)));
2604 return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH
);
2608 hr
= start_schedsvc();
2609 if (hr
!= S_OK
) return hr
;
2611 hr
= RpcStringBindingComposeW(NULL
, ncalrpc
, NULL
, NULL
, NULL
, &binding_str
);
2612 if (hr
!= RPC_S_OK
) return hr
;
2613 hr
= RpcBindingFromStringBindingW(binding_str
, &rpc_handle
);
2614 if (hr
!= RPC_S_OK
) return hr
;
2615 RpcStringFreeW(&binding_str
);
2617 /* Make sure that the connection works */
2618 hr
= SchRpcHighestVersion(&task_svc
->version
);
2619 if (hr
!= S_OK
) return hr
;
2621 TRACE("server version %#x\n", task_svc
->version
);
2623 strcpyW(task_svc
->comp_name
, comp_name
);
2624 task_svc
->connected
= TRUE
;
2629 static HRESULT WINAPI
TaskService_get_Connected(ITaskService
*iface
, VARIANT_BOOL
*connected
)
2631 TaskService
*task_svc
= impl_from_ITaskService(iface
);
2633 TRACE("%p,%p\n", iface
, connected
);
2635 if (!connected
) return E_POINTER
;
2637 *connected
= task_svc
->connected
? VARIANT_TRUE
: VARIANT_FALSE
;
2642 static HRESULT WINAPI
TaskService_get_TargetServer(ITaskService
*iface
, BSTR
*server
)
2644 TaskService
*task_svc
= impl_from_ITaskService(iface
);
2646 TRACE("%p,%p\n", iface
, server
);
2648 if (!server
) return E_POINTER
;
2650 if (!task_svc
->connected
)
2651 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED
);
2653 *server
= SysAllocString(task_svc
->comp_name
);
2654 if (!*server
) return E_OUTOFMEMORY
;
2659 static HRESULT WINAPI
TaskService_get_ConnectedUser(ITaskService
*iface
, BSTR
*user
)
2661 FIXME("%p,%p: stub\n", iface
, user
);
2665 static HRESULT WINAPI
TaskService_get_ConnectedDomain(ITaskService
*iface
, BSTR
*domain
)
2667 FIXME("%p,%p: stub\n", iface
, domain
);
2671 static HRESULT WINAPI
TaskService_get_HighestVersion(ITaskService
*iface
, DWORD
*version
)
2673 TaskService
*task_svc
= impl_from_ITaskService(iface
);
2675 TRACE("%p,%p\n", iface
, version
);
2677 if (!version
) return E_POINTER
;
2679 if (!task_svc
->connected
)
2680 return HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED
);
2682 *version
= task_svc
->version
;
2687 static const ITaskServiceVtbl TaskService_vtbl
=
2689 TaskService_QueryInterface
,
2691 TaskService_Release
,
2692 TaskService_GetTypeInfoCount
,
2693 TaskService_GetTypeInfo
,
2694 TaskService_GetIDsOfNames
,
2696 TaskService_GetFolder
,
2697 TaskService_GetRunningTasks
,
2698 TaskService_NewTask
,
2699 TaskService_Connect
,
2700 TaskService_get_Connected
,
2701 TaskService_get_TargetServer
,
2702 TaskService_get_ConnectedUser
,
2703 TaskService_get_ConnectedDomain
,
2704 TaskService_get_HighestVersion
2707 HRESULT
TaskService_create(void **obj
)
2709 TaskService
*task_svc
;
2711 task_svc
= heap_alloc(sizeof(*task_svc
));
2712 if (!task_svc
) return E_OUTOFMEMORY
;
2714 task_svc
->ITaskService_iface
.lpVtbl
= &TaskService_vtbl
;
2716 task_svc
->connected
= FALSE
;
2717 *obj
= &task_svc
->ITaskService_iface
;
2719 TRACE("created %p\n", *obj
);
2724 void __RPC_FAR
*__RPC_USER
MIDL_user_allocate(SIZE_T n
)
2726 return HeapAlloc(GetProcessHeap(), 0, n
);
2729 void __RPC_USER
MIDL_user_free(void __RPC_FAR
*p
)
2731 HeapFree(GetProcessHeap(), 0, p
);