2 * Copyright (C) 2008 Google (Roy Shea)
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 "mstask_private.h"
20 #include "wine/debug.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(mstask
);
24 static inline TaskImpl
*impl_from_IPersistFile( IPersistFile
*iface
)
26 return (TaskImpl
*) ((char*)(iface
) - FIELD_OFFSET(TaskImpl
, persistVtbl
));
29 static void TaskDestructor(TaskImpl
*This
)
32 HeapFree(GetProcessHeap(), 0, This
->accountName
);
33 HeapFree(GetProcessHeap(), 0, This
->comment
);
34 HeapFree(GetProcessHeap(), 0, This
->parameters
);
35 HeapFree(GetProcessHeap(), 0, This
->taskName
);
36 HeapFree(GetProcessHeap(), 0, This
);
37 InterlockedDecrement(&dll_ref
);
40 static HRESULT WINAPI
MSTASK_ITask_QueryInterface(
45 TaskImpl
* This
= (TaskImpl
*)iface
;
47 TRACE("IID: %s\n", debugstr_guid(riid
));
48 if (ppvObject
== NULL
)
51 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
52 IsEqualGUID(riid
, &IID_ITask
))
54 *ppvObject
= &This
->lpVtbl
;
58 else if (IsEqualGUID(riid
, &IID_IPersistFile
))
60 *ppvObject
= &This
->persistVtbl
;
65 WARN("Unknown interface: %s\n", debugstr_guid(riid
));
70 static ULONG WINAPI
MSTASK_ITask_AddRef(
73 TaskImpl
*This
= (TaskImpl
*)iface
;
76 ref
= InterlockedIncrement(&This
->ref
);
80 static ULONG WINAPI
MSTASK_ITask_Release(
83 TaskImpl
* This
= (TaskImpl
*)iface
;
86 ref
= InterlockedDecrement(&This
->ref
);
92 static HRESULT WINAPI
MSTASK_ITask_CreateTrigger(
95 ITaskTrigger
**ppTrigger
)
97 TRACE("(%p, %p, %p)\n", iface
, piNewTrigger
, ppTrigger
);
98 return TaskTriggerConstructor((LPVOID
*)ppTrigger
);
101 static HRESULT WINAPI
MSTASK_ITask_DeleteTrigger(
105 FIXME("(%p, %d): stub\n", iface
, iTrigger
);
109 static HRESULT WINAPI
MSTASK_ITask_GetTriggerCount(
113 FIXME("(%p, %p): stub\n", iface
, plCount
);
117 static HRESULT WINAPI
MSTASK_ITask_GetTrigger(
120 ITaskTrigger
**ppTrigger
)
122 FIXME("(%p, %d, %p): stub\n", iface
, iTrigger
, ppTrigger
);
126 static HRESULT WINAPI
MSTASK_ITask_GetTriggerString(
129 LPWSTR
*ppwszTrigger
)
131 FIXME("(%p, %d, %p): stub\n", iface
, iTrigger
, ppwszTrigger
);
135 static HRESULT WINAPI
MSTASK_ITask_GetRunTimes(
137 const LPSYSTEMTIME pstBegin
,
138 const LPSYSTEMTIME pstEnd
,
140 LPSYSTEMTIME
*rgstTaskTimes
)
142 FIXME("(%p, %p, %p, %p, %p): stub\n", iface
, pstBegin
, pstEnd
, pCount
,
147 static HRESULT WINAPI
MSTASK_ITask_GetNextRunTime(
149 SYSTEMTIME
*pstNextRun
)
151 FIXME("(%p, %p): stub\n", iface
, pstNextRun
);
155 static HRESULT WINAPI
MSTASK_ITask_SetIdleWait(
158 WORD wDeadlineMinutes
)
160 FIXME("(%p, %d, %d): stub\n", iface
, wIdleMinutes
, wDeadlineMinutes
);
164 static HRESULT WINAPI
MSTASK_ITask_GetIdleWait(
167 WORD
*pwDeadlineMinutes
)
169 FIXME("(%p, %p, %p): stub\n", iface
, pwIdleMinutes
, pwDeadlineMinutes
);
173 static HRESULT WINAPI
MSTASK_ITask_Run(
176 FIXME("(%p): stub\n", iface
);
180 static HRESULT WINAPI
MSTASK_ITask_Terminate(
183 FIXME("(%p): stub\n", iface
);
187 static HRESULT WINAPI
MSTASK_ITask_EditWorkItem(
192 FIXME("(%p, %p, %d): stub\n", iface
, hParent
, dwReserved
);
196 static HRESULT WINAPI
MSTASK_ITask_GetMostRecentRunTime(
198 SYSTEMTIME
*pstLastRun
)
200 FIXME("(%p, %p): stub\n", iface
, pstLastRun
);
204 static HRESULT WINAPI
MSTASK_ITask_GetStatus(
208 FIXME("(%p, %p): stub\n", iface
, phrStatus
);
212 static HRESULT WINAPI
MSTASK_ITask_GetExitCode(
216 FIXME("(%p, %p): stub\n", iface
, pdwExitCode
);
220 static HRESULT WINAPI
MSTASK_ITask_SetComment(
225 TaskImpl
*This
= (TaskImpl
*)iface
;
228 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszComment
));
231 if (pwszComment
[0] == 0)
233 HeapFree(GetProcessHeap(), 0, This
->comment
);
234 This
->comment
= NULL
;
238 /* Set to pwszComment */
239 n
= (lstrlenW(pwszComment
) + 1);
240 tmp_comment
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
242 return E_OUTOFMEMORY
;
243 lstrcpyW(tmp_comment
, pwszComment
);
244 HeapFree(GetProcessHeap(), 0, This
->comment
);
245 This
->comment
= tmp_comment
;
250 static HRESULT WINAPI
MSTASK_ITask_GetComment(
252 LPWSTR
*ppwszComment
)
255 TaskImpl
*This
= (TaskImpl
*)iface
;
257 TRACE("(%p, %p)\n", iface
, ppwszComment
);
259 n
= This
->comment
? lstrlenW(This
->comment
) + 1 : 1;
260 *ppwszComment
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
262 return E_OUTOFMEMORY
;
265 *ppwszComment
[0] = 0;
267 lstrcpyW(*ppwszComment
, This
->comment
);
272 static HRESULT WINAPI
MSTASK_ITask_SetCreator(
276 FIXME("(%p, %p): stub\n", iface
, pwszCreator
);
280 static HRESULT WINAPI
MSTASK_ITask_GetCreator(
282 LPWSTR
*ppwszCreator
)
284 FIXME("(%p, %p): stub\n", iface
, ppwszCreator
);
288 static HRESULT WINAPI
MSTASK_ITask_SetWorkItemData(
293 FIXME("(%p, %d, %p): stub\n", iface
, cBytes
, rgbData
);
297 static HRESULT WINAPI
MSTASK_ITask_GetWorkItemData(
302 FIXME("(%p, %p, %p): stub\n", iface
, pcBytes
, ppBytes
);
306 static HRESULT WINAPI
MSTASK_ITask_SetErrorRetryCount(
310 FIXME("(%p, %d): stub\n", iface
, wRetryCount
);
314 static HRESULT WINAPI
MSTASK_ITask_GetErrorRetryCount(
318 FIXME("(%p, %p): stub\n", iface
, pwRetryCount
);
322 static HRESULT WINAPI
MSTASK_ITask_SetErrorRetryInterval(
326 FIXME("(%p, %d): stub\n", iface
, wRetryInterval
);
330 static HRESULT WINAPI
MSTASK_ITask_GetErrorRetryInterval(
332 WORD
*pwRetryInterval
)
334 FIXME("(%p, %p): stub\n", iface
, pwRetryInterval
);
338 static HRESULT WINAPI
MSTASK_ITask_SetFlags(
342 FIXME("(%p, 0x%08x): stub\n", iface
, dwFlags
);
346 static HRESULT WINAPI
MSTASK_ITask_GetFlags(
350 FIXME("(%p, %p): stub\n", iface
, pdwFlags
);
354 static HRESULT WINAPI
MSTASK_ITask_SetAccountInformation(
356 LPCWSTR pwszAccountName
,
357 LPCWSTR pwszPassword
)
360 TaskImpl
*This
= (TaskImpl
*)iface
;
361 LPWSTR tmp_account_name
;
363 TRACE("(%p, %s, %s): partial stub\n", iface
, debugstr_w(pwszAccountName
),
364 debugstr_w(pwszPassword
));
367 FIXME("Partial stub ignores passwords\n");
369 n
= (lstrlenW(pwszAccountName
) + 1);
370 tmp_account_name
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
371 if (!tmp_account_name
)
372 return E_OUTOFMEMORY
;
373 lstrcpyW(tmp_account_name
, pwszAccountName
);
374 HeapFree(GetProcessHeap(), 0, This
->accountName
);
375 This
->accountName
= tmp_account_name
;
379 static HRESULT WINAPI
MSTASK_ITask_GetAccountInformation(
381 LPWSTR
*ppwszAccountName
)
384 TaskImpl
*This
= (TaskImpl
*)iface
;
386 TRACE("(%p, %p): partial stub\n", iface
, ppwszAccountName
);
388 /* This implements the WinXP behavior when accountName has not yet
389 * set. Win2K behaves differently, returning SCHED_E_CANNOT_OPEN_TASK */
390 if (!This
->accountName
)
391 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
393 n
= (lstrlenW(This
->accountName
) + 1);
394 *ppwszAccountName
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
395 if (!*ppwszAccountName
)
396 return E_OUTOFMEMORY
;
397 lstrcpyW(*ppwszAccountName
, This
->accountName
);
401 static HRESULT WINAPI
MSTASK_ITask_SetApplicationName(
403 LPCWSTR pwszApplicationName
)
406 TaskImpl
*This
= (TaskImpl
*)iface
;
409 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszApplicationName
));
411 /* Empty application name */
412 if (pwszApplicationName
[0] == 0)
414 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
415 This
->applicationName
= NULL
;
419 /* Attempt to set pwszApplicationName to a path resolved application name */
420 n
= SearchPathW(NULL
, pwszApplicationName
, NULL
, 0, NULL
, NULL
);
423 tmp_name
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
425 return E_OUTOFMEMORY
;
426 n
= SearchPathW(NULL
, pwszApplicationName
, NULL
, n
, tmp_name
, NULL
);
429 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
430 This
->applicationName
= tmp_name
;
434 HeapFree(GetProcessHeap(), 0, tmp_name
);
437 /* If unable to path resolve name, simply set to pwszApplicationName */
438 n
= (lstrlenW(pwszApplicationName
) + 1);
439 tmp_name
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
441 return E_OUTOFMEMORY
;
442 lstrcpyW(tmp_name
, pwszApplicationName
);
443 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
444 This
->applicationName
= tmp_name
;
448 static HRESULT WINAPI
MSTASK_ITask_GetApplicationName(
450 LPWSTR
*ppwszApplicationName
)
453 TaskImpl
*This
= (TaskImpl
*)iface
;
455 TRACE("(%p, %p)\n", iface
, ppwszApplicationName
);
457 n
= This
->applicationName
? lstrlenW(This
->applicationName
) + 1 : 1;
458 *ppwszApplicationName
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
459 if (!*ppwszApplicationName
)
460 return E_OUTOFMEMORY
;
462 if (!This
->applicationName
)
463 *ppwszApplicationName
[0] = 0;
465 lstrcpyW(*ppwszApplicationName
, This
->applicationName
);
470 static HRESULT WINAPI
MSTASK_ITask_SetParameters(
472 LPCWSTR pwszParameters
)
475 TaskImpl
*This
= (TaskImpl
*)iface
;
476 LPWSTR tmp_parameters
;
478 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszParameters
));
480 /* Empty parameter list */
481 if (pwszParameters
[0] == 0)
483 HeapFree(GetProcessHeap(), 0, This
->parameters
);
484 This
->parameters
= NULL
;
488 /* Set to pwszParameters */
489 n
= (lstrlenW(pwszParameters
) + 1);
490 tmp_parameters
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
492 return E_OUTOFMEMORY
;
493 lstrcpyW(tmp_parameters
, pwszParameters
);
494 HeapFree(GetProcessHeap(), 0, This
->parameters
);
495 This
->parameters
= tmp_parameters
;
499 static HRESULT WINAPI
MSTASK_ITask_GetParameters(
501 LPWSTR
*ppwszParameters
)
504 TaskImpl
*This
= (TaskImpl
*)iface
;
506 TRACE("(%p, %p)\n", iface
, ppwszParameters
);
508 n
= This
->parameters
? lstrlenW(This
->parameters
) + 1 : 1;
509 *ppwszParameters
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
510 if (!*ppwszParameters
)
511 return E_OUTOFMEMORY
;
513 if (!This
->parameters
)
514 *ppwszParameters
[0] = 0;
516 lstrcpyW(*ppwszParameters
, This
->parameters
);
521 static HRESULT WINAPI
MSTASK_ITask_SetWorkingDirectory(
523 LPCWSTR pwszWorkingDirectory
)
525 FIXME("(%p, %s): stub\n", iface
, debugstr_w(pwszWorkingDirectory
));
529 static HRESULT WINAPI
MSTASK_ITask_GetWorkingDirectory(
531 LPWSTR
*ppwszWorkingDirectory
)
533 FIXME("(%p, %p): stub\n", iface
, ppwszWorkingDirectory
);
537 static HRESULT WINAPI
MSTASK_ITask_SetPriority(
541 FIXME("(%p, 0x%08x): stub\n", iface
, dwPriority
);
545 static HRESULT WINAPI
MSTASK_ITask_GetPriority(
549 FIXME("(%p, %p): stub\n", iface
, pdwPriority
);
553 static HRESULT WINAPI
MSTASK_ITask_SetTaskFlags(
557 FIXME("(%p, 0x%08x): stub\n", iface
, dwFlags
);
561 static HRESULT WINAPI
MSTASK_ITask_GetTaskFlags(
565 FIXME("(%p, %p): stub\n", iface
, pdwFlags
);
569 static HRESULT WINAPI
MSTASK_ITask_SetMaxRunTime(
573 TaskImpl
*This
= (TaskImpl
*)iface
;
575 TRACE("(%p, %d)\n", iface
, dwMaxRunTime
);
577 This
->maxRunTime
= dwMaxRunTime
;
581 static HRESULT WINAPI
MSTASK_ITask_GetMaxRunTime(
583 DWORD
*pdwMaxRunTime
)
585 TaskImpl
*This
= (TaskImpl
*)iface
;
587 TRACE("(%p, %p)\n", iface
, pdwMaxRunTime
);
589 *pdwMaxRunTime
= This
->maxRunTime
;
593 static HRESULT WINAPI
MSTASK_IPersistFile_QueryInterface(
598 TaskImpl
*This
= impl_from_IPersistFile(iface
);
599 TRACE("(%p, %s, %p)\n", iface
, debugstr_guid(riid
), ppvObject
);
600 return ITask_QueryInterface((ITask
*) This
, riid
, ppvObject
);
603 static ULONG WINAPI
MSTASK_IPersistFile_AddRef(
606 TaskImpl
*This
= impl_from_IPersistFile(iface
);
609 ref
= InterlockedIncrement(&This
->ref
);
613 static ULONG WINAPI
MSTASK_IPersistFile_Release(
616 TaskImpl
*This
= impl_from_IPersistFile(iface
);
619 ref
= InterlockedDecrement(&This
->ref
);
621 TaskDestructor(This
);
625 static HRESULT WINAPI
MSTASK_IPersistFile_GetClassID(
629 FIXME("(%p, %p): stub\n", iface
, pClassID
);
633 static HRESULT WINAPI
MSTASK_IPersistFile_IsDirty(
636 FIXME("(%p): stub\n", iface
);
640 static HRESULT WINAPI
MSTASK_IPersistFile_Load(
642 LPCOLESTR pszFileName
,
645 FIXME("(%p, %p, 0x%08x): stub\n", iface
, pszFileName
, dwMode
);
649 static HRESULT WINAPI
MSTASK_IPersistFile_Save(
651 LPCOLESTR pszFileName
,
654 FIXME("(%p, %p, %d): stub\n", iface
, pszFileName
, fRemember
);
655 WARN("Returning S_OK but not writing to disk: %s %d\n",
656 debugstr_w(pszFileName
), fRemember
);
660 static HRESULT WINAPI
MSTASK_IPersistFile_SaveCompleted(
662 LPCOLESTR pszFileName
)
664 FIXME("(%p, %p): stub\n", iface
, pszFileName
);
668 static HRESULT WINAPI
MSTASK_IPersistFile_GetCurFile(
670 LPOLESTR
*ppszFileName
)
672 FIXME("(%p, %p): stub\n", iface
, ppszFileName
);
677 static const ITaskVtbl MSTASK_ITaskVtbl
=
679 MSTASK_ITask_QueryInterface
,
681 MSTASK_ITask_Release
,
682 MSTASK_ITask_CreateTrigger
,
683 MSTASK_ITask_DeleteTrigger
,
684 MSTASK_ITask_GetTriggerCount
,
685 MSTASK_ITask_GetTrigger
,
686 MSTASK_ITask_GetTriggerString
,
687 MSTASK_ITask_GetRunTimes
,
688 MSTASK_ITask_GetNextRunTime
,
689 MSTASK_ITask_SetIdleWait
,
690 MSTASK_ITask_GetIdleWait
,
692 MSTASK_ITask_Terminate
,
693 MSTASK_ITask_EditWorkItem
,
694 MSTASK_ITask_GetMostRecentRunTime
,
695 MSTASK_ITask_GetStatus
,
696 MSTASK_ITask_GetExitCode
,
697 MSTASK_ITask_SetComment
,
698 MSTASK_ITask_GetComment
,
699 MSTASK_ITask_SetCreator
,
700 MSTASK_ITask_GetCreator
,
701 MSTASK_ITask_SetWorkItemData
,
702 MSTASK_ITask_GetWorkItemData
,
703 MSTASK_ITask_SetErrorRetryCount
,
704 MSTASK_ITask_GetErrorRetryCount
,
705 MSTASK_ITask_SetErrorRetryInterval
,
706 MSTASK_ITask_GetErrorRetryInterval
,
707 MSTASK_ITask_SetFlags
,
708 MSTASK_ITask_GetFlags
,
709 MSTASK_ITask_SetAccountInformation
,
710 MSTASK_ITask_GetAccountInformation
,
711 MSTASK_ITask_SetApplicationName
,
712 MSTASK_ITask_GetApplicationName
,
713 MSTASK_ITask_SetParameters
,
714 MSTASK_ITask_GetParameters
,
715 MSTASK_ITask_SetWorkingDirectory
,
716 MSTASK_ITask_GetWorkingDirectory
,
717 MSTASK_ITask_SetPriority
,
718 MSTASK_ITask_GetPriority
,
719 MSTASK_ITask_SetTaskFlags
,
720 MSTASK_ITask_GetTaskFlags
,
721 MSTASK_ITask_SetMaxRunTime
,
722 MSTASK_ITask_GetMaxRunTime
725 static const IPersistFileVtbl MSTASK_IPersistFileVtbl
=
727 MSTASK_IPersistFile_QueryInterface
,
728 MSTASK_IPersistFile_AddRef
,
729 MSTASK_IPersistFile_Release
,
730 MSTASK_IPersistFile_GetClassID
,
731 MSTASK_IPersistFile_IsDirty
,
732 MSTASK_IPersistFile_Load
,
733 MSTASK_IPersistFile_Save
,
734 MSTASK_IPersistFile_SaveCompleted
,
735 MSTASK_IPersistFile_GetCurFile
738 HRESULT
TaskConstructor(LPCWSTR pwszTaskName
, LPVOID
*ppObj
)
743 TRACE("(%s, %p)\n", debugstr_w(pwszTaskName
), ppObj
);
745 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
747 return E_OUTOFMEMORY
;
749 This
->lpVtbl
= &MSTASK_ITaskVtbl
;
750 This
->persistVtbl
= &MSTASK_IPersistFileVtbl
;
752 n
= (lstrlenW(pwszTaskName
) + 1) * sizeof(WCHAR
);
753 This
->taskName
= HeapAlloc(GetProcessHeap(), 0, n
);
756 HeapFree(GetProcessHeap(), 0, This
);
757 return E_OUTOFMEMORY
;
759 lstrcpyW(This
->taskName
, pwszTaskName
);
760 This
->applicationName
= NULL
;
761 This
->parameters
= NULL
;
762 This
->comment
= NULL
;
763 This
->accountName
= NULL
;
765 /* Default time is 3 days = 259200000 ms */
766 This
->maxRunTime
= 259200000;
768 *ppObj
= &This
->lpVtbl
;
769 InterlockedIncrement(&dll_ref
);