* Sync up to trunk head (r64829).
[reactos.git] / dll / win32 / mstask / task.c
1 /*
2 * Copyright (C) 2008 Google (Roy Shea)
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "mstask_private.h"
20
21 typedef struct
22 {
23 ITask ITask_iface;
24 IPersistFile IPersistFile_iface;
25 LONG ref;
26 LPWSTR taskName;
27 LPWSTR applicationName;
28 LPWSTR parameters;
29 LPWSTR comment;
30 DWORD maxRunTime;
31 LPWSTR accountName;
32 } TaskImpl;
33
34 static inline TaskImpl *impl_from_ITask(ITask *iface)
35 {
36 return CONTAINING_RECORD(iface, TaskImpl, ITask_iface);
37 }
38
39 static inline TaskImpl *impl_from_IPersistFile( IPersistFile *iface )
40 {
41 return CONTAINING_RECORD(iface, TaskImpl, IPersistFile_iface);
42 }
43
44 static void TaskDestructor(TaskImpl *This)
45 {
46 TRACE("%p\n", This);
47 HeapFree(GetProcessHeap(), 0, This->accountName);
48 HeapFree(GetProcessHeap(), 0, This->comment);
49 HeapFree(GetProcessHeap(), 0, This->parameters);
50 HeapFree(GetProcessHeap(), 0, This->taskName);
51 HeapFree(GetProcessHeap(), 0, This);
52 InterlockedDecrement(&dll_ref);
53 }
54
55 static HRESULT WINAPI MSTASK_ITask_QueryInterface(
56 ITask* iface,
57 REFIID riid,
58 void **ppvObject)
59 {
60 TaskImpl * This = impl_from_ITask(iface);
61
62 TRACE("IID: %s\n", debugstr_guid(riid));
63 if (ppvObject == NULL)
64 return E_POINTER;
65
66 if (IsEqualGUID(riid, &IID_IUnknown) ||
67 IsEqualGUID(riid, &IID_ITask))
68 {
69 *ppvObject = &This->ITask_iface;
70 ITask_AddRef(iface);
71 return S_OK;
72 }
73 else if (IsEqualGUID(riid, &IID_IPersistFile))
74 {
75 *ppvObject = &This->IPersistFile_iface;
76 ITask_AddRef(iface);
77 return S_OK;
78 }
79
80 WARN("Unknown interface: %s\n", debugstr_guid(riid));
81 *ppvObject = NULL;
82 return E_NOINTERFACE;
83 }
84
85 static ULONG WINAPI MSTASK_ITask_AddRef(
86 ITask* iface)
87 {
88 TaskImpl *This = impl_from_ITask(iface);
89 ULONG ref;
90 TRACE("\n");
91 ref = InterlockedIncrement(&This->ref);
92 return ref;
93 }
94
95 static ULONG WINAPI MSTASK_ITask_Release(
96 ITask* iface)
97 {
98 TaskImpl * This = impl_from_ITask(iface);
99 ULONG ref;
100 TRACE("\n");
101 ref = InterlockedDecrement(&This->ref);
102 if (ref == 0)
103 TaskDestructor(This);
104 return ref;
105 }
106
107 static HRESULT WINAPI MSTASK_ITask_CreateTrigger(
108 ITask* iface,
109 WORD *piNewTrigger,
110 ITaskTrigger **ppTrigger)
111 {
112 TRACE("(%p, %p, %p)\n", iface, piNewTrigger, ppTrigger);
113 return TaskTriggerConstructor((LPVOID *)ppTrigger);
114 }
115
116 static HRESULT WINAPI MSTASK_ITask_DeleteTrigger(
117 ITask* iface,
118 WORD iTrigger)
119 {
120 FIXME("(%p, %d): stub\n", iface, iTrigger);
121 return E_NOTIMPL;
122 }
123
124 static HRESULT WINAPI MSTASK_ITask_GetTriggerCount(
125 ITask* iface,
126 WORD *plCount)
127 {
128 FIXME("(%p, %p): stub\n", iface, plCount);
129 return E_NOTIMPL;
130 }
131
132 static HRESULT WINAPI MSTASK_ITask_GetTrigger(
133 ITask* iface,
134 WORD iTrigger,
135 ITaskTrigger **ppTrigger)
136 {
137 FIXME("(%p, %d, %p): stub\n", iface, iTrigger, ppTrigger);
138 return E_NOTIMPL;
139 }
140
141 static HRESULT WINAPI MSTASK_ITask_GetTriggerString(
142 ITask* iface,
143 WORD iTrigger,
144 LPWSTR *ppwszTrigger)
145 {
146 FIXME("(%p, %d, %p): stub\n", iface, iTrigger, ppwszTrigger);
147 return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI MSTASK_ITask_GetRunTimes(
151 ITask* iface,
152 const LPSYSTEMTIME pstBegin,
153 const LPSYSTEMTIME pstEnd,
154 WORD *pCount,
155 LPSYSTEMTIME *rgstTaskTimes)
156 {
157 FIXME("(%p, %p, %p, %p, %p): stub\n", iface, pstBegin, pstEnd, pCount,
158 rgstTaskTimes);
159 return E_NOTIMPL;
160 }
161
162 static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(
163 ITask* iface,
164 SYSTEMTIME *pstNextRun)
165 {
166 FIXME("(%p, %p): stub\n", iface, pstNextRun);
167 return E_NOTIMPL;
168 }
169
170 static HRESULT WINAPI MSTASK_ITask_SetIdleWait(
171 ITask* iface,
172 WORD wIdleMinutes,
173 WORD wDeadlineMinutes)
174 {
175 FIXME("(%p, %d, %d): stub\n", iface, wIdleMinutes, wDeadlineMinutes);
176 return E_NOTIMPL;
177 }
178
179 static HRESULT WINAPI MSTASK_ITask_GetIdleWait(
180 ITask* iface,
181 WORD *pwIdleMinutes,
182 WORD *pwDeadlineMinutes)
183 {
184 FIXME("(%p, %p, %p): stub\n", iface, pwIdleMinutes, pwDeadlineMinutes);
185 return E_NOTIMPL;
186 }
187
188 static HRESULT WINAPI MSTASK_ITask_Run(
189 ITask* iface)
190 {
191 FIXME("(%p): stub\n", iface);
192 return E_NOTIMPL;
193 }
194
195 static HRESULT WINAPI MSTASK_ITask_Terminate(
196 ITask* iface)
197 {
198 FIXME("(%p): stub\n", iface);
199 return E_NOTIMPL;
200 }
201
202 static HRESULT WINAPI MSTASK_ITask_EditWorkItem(
203 ITask* iface,
204 HWND hParent,
205 DWORD dwReserved)
206 {
207 FIXME("(%p, %p, %d): stub\n", iface, hParent, dwReserved);
208 return E_NOTIMPL;
209 }
210
211 static HRESULT WINAPI MSTASK_ITask_GetMostRecentRunTime(
212 ITask* iface,
213 SYSTEMTIME *pstLastRun)
214 {
215 FIXME("(%p, %p): stub\n", iface, pstLastRun);
216 return E_NOTIMPL;
217 }
218
219 static HRESULT WINAPI MSTASK_ITask_GetStatus(
220 ITask* iface,
221 HRESULT *phrStatus)
222 {
223 FIXME("(%p, %p): stub\n", iface, phrStatus);
224 return E_NOTIMPL;
225 }
226
227 static HRESULT WINAPI MSTASK_ITask_GetExitCode(
228 ITask* iface,
229 DWORD *pdwExitCode)
230 {
231 FIXME("(%p, %p): stub\n", iface, pdwExitCode);
232 return E_NOTIMPL;
233 }
234
235 static HRESULT WINAPI MSTASK_ITask_SetComment(
236 ITask* iface,
237 LPCWSTR pwszComment)
238 {
239 DWORD n;
240 TaskImpl *This = impl_from_ITask(iface);
241 LPWSTR tmp_comment;
242
243 TRACE("(%p, %s)\n", iface, debugstr_w(pwszComment));
244
245 /* Empty comment */
246 if (pwszComment[0] == 0)
247 {
248 HeapFree(GetProcessHeap(), 0, This->comment);
249 This->comment = NULL;
250 return S_OK;
251 }
252
253 /* Set to pwszComment */
254 n = (lstrlenW(pwszComment) + 1);
255 tmp_comment = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
256 if (!tmp_comment)
257 return E_OUTOFMEMORY;
258 lstrcpyW(tmp_comment, pwszComment);
259 HeapFree(GetProcessHeap(), 0, This->comment);
260 This->comment = tmp_comment;
261
262 return S_OK;
263 }
264
265 static HRESULT WINAPI MSTASK_ITask_GetComment(
266 ITask* iface,
267 LPWSTR *ppwszComment)
268 {
269 DWORD n;
270 TaskImpl *This = impl_from_ITask(iface);
271
272 TRACE("(%p, %p)\n", iface, ppwszComment);
273
274 n = This->comment ? lstrlenW(This->comment) + 1 : 1;
275 *ppwszComment = CoTaskMemAlloc(n * sizeof(WCHAR));
276 if (!*ppwszComment)
277 return E_OUTOFMEMORY;
278
279 if (!This->comment)
280 *ppwszComment[0] = 0;
281 else
282 lstrcpyW(*ppwszComment, This->comment);
283
284 return S_OK;
285 }
286
287 static HRESULT WINAPI MSTASK_ITask_SetCreator(
288 ITask* iface,
289 LPCWSTR pwszCreator)
290 {
291 FIXME("(%p, %p): stub\n", iface, pwszCreator);
292 return E_NOTIMPL;
293 }
294
295 static HRESULT WINAPI MSTASK_ITask_GetCreator(
296 ITask* iface,
297 LPWSTR *ppwszCreator)
298 {
299 FIXME("(%p, %p): stub\n", iface, ppwszCreator);
300 return E_NOTIMPL;
301 }
302
303 static HRESULT WINAPI MSTASK_ITask_SetWorkItemData(
304 ITask* iface,
305 WORD cBytes,
306 BYTE rgbData[])
307 {
308 FIXME("(%p, %d, %p): stub\n", iface, cBytes, rgbData);
309 return E_NOTIMPL;
310 }
311
312 static HRESULT WINAPI MSTASK_ITask_GetWorkItemData(
313 ITask* iface,
314 WORD *pcBytes,
315 BYTE **ppBytes)
316 {
317 FIXME("(%p, %p, %p): stub\n", iface, pcBytes, ppBytes);
318 return E_NOTIMPL;
319 }
320
321 static HRESULT WINAPI MSTASK_ITask_SetErrorRetryCount(
322 ITask* iface,
323 WORD wRetryCount)
324 {
325 FIXME("(%p, %d): stub\n", iface, wRetryCount);
326 return E_NOTIMPL;
327 }
328
329 static HRESULT WINAPI MSTASK_ITask_GetErrorRetryCount(
330 ITask* iface,
331 WORD *pwRetryCount)
332 {
333 FIXME("(%p, %p): stub\n", iface, pwRetryCount);
334 return E_NOTIMPL;
335 }
336
337 static HRESULT WINAPI MSTASK_ITask_SetErrorRetryInterval(
338 ITask* iface,
339 WORD wRetryInterval)
340 {
341 FIXME("(%p, %d): stub\n", iface, wRetryInterval);
342 return E_NOTIMPL;
343 }
344
345 static HRESULT WINAPI MSTASK_ITask_GetErrorRetryInterval(
346 ITask* iface,
347 WORD *pwRetryInterval)
348 {
349 FIXME("(%p, %p): stub\n", iface, pwRetryInterval);
350 return E_NOTIMPL;
351 }
352
353 static HRESULT WINAPI MSTASK_ITask_SetFlags(
354 ITask* iface,
355 DWORD dwFlags)
356 {
357 FIXME("(%p, 0x%08x): stub\n", iface, dwFlags);
358 return E_NOTIMPL;
359 }
360
361 static HRESULT WINAPI MSTASK_ITask_GetFlags(
362 ITask* iface,
363 DWORD *pdwFlags)
364 {
365 FIXME("(%p, %p): stub\n", iface, pdwFlags);
366 return E_NOTIMPL;
367 }
368
369 static HRESULT WINAPI MSTASK_ITask_SetAccountInformation(
370 ITask* iface,
371 LPCWSTR pwszAccountName,
372 LPCWSTR pwszPassword)
373 {
374 DWORD n;
375 TaskImpl *This = impl_from_ITask(iface);
376 LPWSTR tmp_account_name;
377
378 TRACE("(%p, %s, %s): partial stub\n", iface, debugstr_w(pwszAccountName),
379 debugstr_w(pwszPassword));
380
381 if (pwszPassword)
382 FIXME("Partial stub ignores passwords\n");
383
384 n = (lstrlenW(pwszAccountName) + 1);
385 tmp_account_name = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
386 if (!tmp_account_name)
387 return E_OUTOFMEMORY;
388 lstrcpyW(tmp_account_name, pwszAccountName);
389 HeapFree(GetProcessHeap(), 0, This->accountName);
390 This->accountName = tmp_account_name;
391 return S_OK;
392 }
393
394 static HRESULT WINAPI MSTASK_ITask_GetAccountInformation(
395 ITask* iface,
396 LPWSTR *ppwszAccountName)
397 {
398 DWORD n;
399 TaskImpl *This = impl_from_ITask(iface);
400
401 TRACE("(%p, %p): partial stub\n", iface, ppwszAccountName);
402
403 /* This implements the WinXP behavior when accountName has not yet
404 * set. Win2K behaves differently, returning SCHED_E_CANNOT_OPEN_TASK */
405 if (!This->accountName)
406 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
407
408 n = (lstrlenW(This->accountName) + 1);
409 *ppwszAccountName = CoTaskMemAlloc(n * sizeof(WCHAR));
410 if (!*ppwszAccountName)
411 return E_OUTOFMEMORY;
412 lstrcpyW(*ppwszAccountName, This->accountName);
413 return S_OK;
414 }
415
416 static HRESULT WINAPI MSTASK_ITask_SetApplicationName(
417 ITask* iface,
418 LPCWSTR pwszApplicationName)
419 {
420 DWORD n;
421 TaskImpl *This = impl_from_ITask(iface);
422 LPWSTR tmp_name;
423
424 TRACE("(%p, %s)\n", iface, debugstr_w(pwszApplicationName));
425
426 /* Empty application name */
427 if (pwszApplicationName[0] == 0)
428 {
429 HeapFree(GetProcessHeap(), 0, This->applicationName);
430 This->applicationName = NULL;
431 return S_OK;
432 }
433
434 /* Attempt to set pwszApplicationName to a path resolved application name */
435 n = SearchPathW(NULL, pwszApplicationName, NULL, 0, NULL, NULL);
436 if (n)
437 {
438 tmp_name = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
439 if (!tmp_name)
440 return E_OUTOFMEMORY;
441 n = SearchPathW(NULL, pwszApplicationName, NULL, n, tmp_name, NULL);
442 if (n)
443 {
444 HeapFree(GetProcessHeap(), 0, This->applicationName);
445 This->applicationName = tmp_name;
446 return S_OK;
447 }
448 else
449 HeapFree(GetProcessHeap(), 0, tmp_name);
450 }
451
452 /* If unable to path resolve name, simply set to pwszApplicationName */
453 n = (lstrlenW(pwszApplicationName) + 1);
454 tmp_name = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
455 if (!tmp_name)
456 return E_OUTOFMEMORY;
457 lstrcpyW(tmp_name, pwszApplicationName);
458 HeapFree(GetProcessHeap(), 0, This->applicationName);
459 This->applicationName = tmp_name;
460 return S_OK;
461 }
462
463 static HRESULT WINAPI MSTASK_ITask_GetApplicationName(
464 ITask* iface,
465 LPWSTR *ppwszApplicationName)
466 {
467 DWORD n;
468 TaskImpl *This = impl_from_ITask(iface);
469
470 TRACE("(%p, %p)\n", iface, ppwszApplicationName);
471
472 n = This->applicationName ? lstrlenW(This->applicationName) + 1 : 1;
473 *ppwszApplicationName = CoTaskMemAlloc(n * sizeof(WCHAR));
474 if (!*ppwszApplicationName)
475 return E_OUTOFMEMORY;
476
477 if (!This->applicationName)
478 *ppwszApplicationName[0] = 0;
479 else
480 lstrcpyW(*ppwszApplicationName, This->applicationName);
481
482 return S_OK;
483 }
484
485 static HRESULT WINAPI MSTASK_ITask_SetParameters(
486 ITask* iface,
487 LPCWSTR pwszParameters)
488 {
489 DWORD n;
490 TaskImpl *This = impl_from_ITask(iface);
491 LPWSTR tmp_parameters;
492
493 TRACE("(%p, %s)\n", iface, debugstr_w(pwszParameters));
494
495 /* Empty parameter list */
496 if (pwszParameters[0] == 0)
497 {
498 HeapFree(GetProcessHeap(), 0, This->parameters);
499 This->parameters = NULL;
500 return S_OK;
501 }
502
503 /* Set to pwszParameters */
504 n = (lstrlenW(pwszParameters) + 1);
505 tmp_parameters = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
506 if (!tmp_parameters)
507 return E_OUTOFMEMORY;
508 lstrcpyW(tmp_parameters, pwszParameters);
509 HeapFree(GetProcessHeap(), 0, This->parameters);
510 This->parameters = tmp_parameters;
511 return S_OK;
512 }
513
514 static HRESULT WINAPI MSTASK_ITask_GetParameters(
515 ITask* iface,
516 LPWSTR *ppwszParameters)
517 {
518 DWORD n;
519 TaskImpl *This = impl_from_ITask(iface);
520
521 TRACE("(%p, %p)\n", iface, ppwszParameters);
522
523 n = This->parameters ? lstrlenW(This->parameters) + 1 : 1;
524 *ppwszParameters = CoTaskMemAlloc(n * sizeof(WCHAR));
525 if (!*ppwszParameters)
526 return E_OUTOFMEMORY;
527
528 if (!This->parameters)
529 *ppwszParameters[0] = 0;
530 else
531 lstrcpyW(*ppwszParameters, This->parameters);
532
533 return S_OK;
534 }
535
536 static HRESULT WINAPI MSTASK_ITask_SetWorkingDirectory(
537 ITask* iface,
538 LPCWSTR pwszWorkingDirectory)
539 {
540 FIXME("(%p, %s): stub\n", iface, debugstr_w(pwszWorkingDirectory));
541 return E_NOTIMPL;
542 }
543
544 static HRESULT WINAPI MSTASK_ITask_GetWorkingDirectory(
545 ITask* iface,
546 LPWSTR *ppwszWorkingDirectory)
547 {
548 FIXME("(%p, %p): stub\n", iface, ppwszWorkingDirectory);
549 return E_NOTIMPL;
550 }
551
552 static HRESULT WINAPI MSTASK_ITask_SetPriority(
553 ITask* iface,
554 DWORD dwPriority)
555 {
556 FIXME("(%p, 0x%08x): stub\n", iface, dwPriority);
557 return E_NOTIMPL;
558 }
559
560 static HRESULT WINAPI MSTASK_ITask_GetPriority(
561 ITask* iface,
562 DWORD *pdwPriority)
563 {
564 FIXME("(%p, %p): stub\n", iface, pdwPriority);
565 return E_NOTIMPL;
566 }
567
568 static HRESULT WINAPI MSTASK_ITask_SetTaskFlags(
569 ITask* iface,
570 DWORD dwFlags)
571 {
572 FIXME("(%p, 0x%08x): stub\n", iface, dwFlags);
573 return E_NOTIMPL;
574 }
575
576 static HRESULT WINAPI MSTASK_ITask_GetTaskFlags(
577 ITask* iface,
578 DWORD *pdwFlags)
579 {
580 FIXME("(%p, %p): stub\n", iface, pdwFlags);
581 return E_NOTIMPL;
582 }
583
584 static HRESULT WINAPI MSTASK_ITask_SetMaxRunTime(
585 ITask* iface,
586 DWORD dwMaxRunTime)
587 {
588 TaskImpl *This = impl_from_ITask(iface);
589
590 TRACE("(%p, %d)\n", iface, dwMaxRunTime);
591
592 This->maxRunTime = dwMaxRunTime;
593 return S_OK;
594 }
595
596 static HRESULT WINAPI MSTASK_ITask_GetMaxRunTime(
597 ITask* iface,
598 DWORD *pdwMaxRunTime)
599 {
600 TaskImpl *This = impl_from_ITask(iface);
601
602 TRACE("(%p, %p)\n", iface, pdwMaxRunTime);
603
604 *pdwMaxRunTime = This->maxRunTime;
605 return S_OK;
606 }
607
608 static HRESULT WINAPI MSTASK_IPersistFile_QueryInterface(
609 IPersistFile* iface,
610 REFIID riid,
611 void **ppvObject)
612 {
613 TaskImpl *This = impl_from_IPersistFile(iface);
614 TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), ppvObject);
615 return ITask_QueryInterface(&This->ITask_iface, riid, ppvObject);
616 }
617
618 static ULONG WINAPI MSTASK_IPersistFile_AddRef(
619 IPersistFile* iface)
620 {
621 TaskImpl *This = impl_from_IPersistFile(iface);
622 ULONG ref;
623 TRACE("\n");
624 ref = InterlockedIncrement(&This->ref);
625 return ref;
626 }
627
628 static ULONG WINAPI MSTASK_IPersistFile_Release(
629 IPersistFile* iface)
630 {
631 TaskImpl *This = impl_from_IPersistFile(iface);
632 ULONG ref;
633 TRACE("\n");
634 ref = InterlockedDecrement(&This->ref);
635 if (ref == 0)
636 TaskDestructor(This);
637 return ref;
638 }
639
640 static HRESULT WINAPI MSTASK_IPersistFile_GetClassID(
641 IPersistFile* iface,
642 CLSID *pClassID)
643 {
644 FIXME("(%p, %p): stub\n", iface, pClassID);
645 return E_NOTIMPL;
646 }
647
648 static HRESULT WINAPI MSTASK_IPersistFile_IsDirty(
649 IPersistFile* iface)
650 {
651 FIXME("(%p): stub\n", iface);
652 return E_NOTIMPL;
653 }
654
655 static HRESULT WINAPI MSTASK_IPersistFile_Load(
656 IPersistFile* iface,
657 LPCOLESTR pszFileName,
658 DWORD dwMode)
659 {
660 FIXME("(%p, %p, 0x%08x): stub\n", iface, pszFileName, dwMode);
661 return E_NOTIMPL;
662 }
663
664 static HRESULT WINAPI MSTASK_IPersistFile_Save(
665 IPersistFile* iface,
666 LPCOLESTR pszFileName,
667 BOOL fRemember)
668 {
669 FIXME("(%p, %p, %d): stub\n", iface, pszFileName, fRemember);
670 WARN("Returning S_OK but not writing to disk: %s %d\n",
671 debugstr_w(pszFileName), fRemember);
672 return S_OK;
673 }
674
675 static HRESULT WINAPI MSTASK_IPersistFile_SaveCompleted(
676 IPersistFile* iface,
677 LPCOLESTR pszFileName)
678 {
679 FIXME("(%p, %p): stub\n", iface, pszFileName);
680 return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI MSTASK_IPersistFile_GetCurFile(
684 IPersistFile* iface,
685 LPOLESTR *ppszFileName)
686 {
687 FIXME("(%p, %p): stub\n", iface, ppszFileName);
688 return E_NOTIMPL;
689 }
690
691
692 static const ITaskVtbl MSTASK_ITaskVtbl =
693 {
694 MSTASK_ITask_QueryInterface,
695 MSTASK_ITask_AddRef,
696 MSTASK_ITask_Release,
697 MSTASK_ITask_CreateTrigger,
698 MSTASK_ITask_DeleteTrigger,
699 MSTASK_ITask_GetTriggerCount,
700 MSTASK_ITask_GetTrigger,
701 MSTASK_ITask_GetTriggerString,
702 MSTASK_ITask_GetRunTimes,
703 MSTASK_ITask_GetNextRunTime,
704 MSTASK_ITask_SetIdleWait,
705 MSTASK_ITask_GetIdleWait,
706 MSTASK_ITask_Run,
707 MSTASK_ITask_Terminate,
708 MSTASK_ITask_EditWorkItem,
709 MSTASK_ITask_GetMostRecentRunTime,
710 MSTASK_ITask_GetStatus,
711 MSTASK_ITask_GetExitCode,
712 MSTASK_ITask_SetComment,
713 MSTASK_ITask_GetComment,
714 MSTASK_ITask_SetCreator,
715 MSTASK_ITask_GetCreator,
716 MSTASK_ITask_SetWorkItemData,
717 MSTASK_ITask_GetWorkItemData,
718 MSTASK_ITask_SetErrorRetryCount,
719 MSTASK_ITask_GetErrorRetryCount,
720 MSTASK_ITask_SetErrorRetryInterval,
721 MSTASK_ITask_GetErrorRetryInterval,
722 MSTASK_ITask_SetFlags,
723 MSTASK_ITask_GetFlags,
724 MSTASK_ITask_SetAccountInformation,
725 MSTASK_ITask_GetAccountInformation,
726 MSTASK_ITask_SetApplicationName,
727 MSTASK_ITask_GetApplicationName,
728 MSTASK_ITask_SetParameters,
729 MSTASK_ITask_GetParameters,
730 MSTASK_ITask_SetWorkingDirectory,
731 MSTASK_ITask_GetWorkingDirectory,
732 MSTASK_ITask_SetPriority,
733 MSTASK_ITask_GetPriority,
734 MSTASK_ITask_SetTaskFlags,
735 MSTASK_ITask_GetTaskFlags,
736 MSTASK_ITask_SetMaxRunTime,
737 MSTASK_ITask_GetMaxRunTime
738 };
739
740 static const IPersistFileVtbl MSTASK_IPersistFileVtbl =
741 {
742 MSTASK_IPersistFile_QueryInterface,
743 MSTASK_IPersistFile_AddRef,
744 MSTASK_IPersistFile_Release,
745 MSTASK_IPersistFile_GetClassID,
746 MSTASK_IPersistFile_IsDirty,
747 MSTASK_IPersistFile_Load,
748 MSTASK_IPersistFile_Save,
749 MSTASK_IPersistFile_SaveCompleted,
750 MSTASK_IPersistFile_GetCurFile
751 };
752
753 HRESULT TaskConstructor(LPCWSTR pwszTaskName, LPVOID *ppObj)
754 {
755 TaskImpl *This;
756 int n;
757
758 TRACE("(%s, %p)\n", debugstr_w(pwszTaskName), ppObj);
759
760 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
761 if (!This)
762 return E_OUTOFMEMORY;
763
764 This->ITask_iface.lpVtbl = &MSTASK_ITaskVtbl;
765 This->IPersistFile_iface.lpVtbl = &MSTASK_IPersistFileVtbl;
766 This->ref = 1;
767 n = (lstrlenW(pwszTaskName) + 1) * sizeof(WCHAR);
768 This->taskName = HeapAlloc(GetProcessHeap(), 0, n);
769 if (!This->taskName)
770 {
771 HeapFree(GetProcessHeap(), 0, This);
772 return E_OUTOFMEMORY;
773 }
774 lstrcpyW(This->taskName, pwszTaskName);
775 This->applicationName = NULL;
776 This->parameters = NULL;
777 This->comment = NULL;
778 This->accountName = NULL;
779
780 /* Default time is 3 days = 259200000 ms */
781 This->maxRunTime = 259200000;
782
783 *ppObj = &This->ITask_iface;
784 InterlockedIncrement(&dll_ref);
785 return S_OK;
786 }