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
);
27 IPersistFile IPersistFile_iface
;
30 LPWSTR applicationName
;
37 static inline TaskImpl
*impl_from_ITask(ITask
*iface
)
39 return CONTAINING_RECORD(iface
, TaskImpl
, ITask_iface
);
42 static inline TaskImpl
*impl_from_IPersistFile( IPersistFile
*iface
)
44 return CONTAINING_RECORD(iface
, TaskImpl
, IPersistFile_iface
);
47 static void TaskDestructor(TaskImpl
*This
)
50 HeapFree(GetProcessHeap(), 0, This
->accountName
);
51 HeapFree(GetProcessHeap(), 0, This
->comment
);
52 HeapFree(GetProcessHeap(), 0, This
->parameters
);
53 HeapFree(GetProcessHeap(), 0, This
->taskName
);
54 HeapFree(GetProcessHeap(), 0, This
);
55 InterlockedDecrement(&dll_ref
);
58 static HRESULT WINAPI
MSTASK_ITask_QueryInterface(
63 TaskImpl
* This
= impl_from_ITask(iface
);
65 TRACE("IID: %s\n", debugstr_guid(riid
));
66 if (ppvObject
== NULL
)
69 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
70 IsEqualGUID(riid
, &IID_ITask
))
72 *ppvObject
= &This
->ITask_iface
;
76 else if (IsEqualGUID(riid
, &IID_IPersistFile
))
78 *ppvObject
= &This
->IPersistFile_iface
;
83 WARN("Unknown interface: %s\n", debugstr_guid(riid
));
88 static ULONG WINAPI
MSTASK_ITask_AddRef(
91 TaskImpl
*This
= impl_from_ITask(iface
);
94 ref
= InterlockedIncrement(&This
->ref
);
98 static ULONG WINAPI
MSTASK_ITask_Release(
101 TaskImpl
* This
= impl_from_ITask(iface
);
104 ref
= InterlockedDecrement(&This
->ref
);
106 TaskDestructor(This
);
110 static HRESULT WINAPI
MSTASK_ITask_CreateTrigger(
113 ITaskTrigger
**ppTrigger
)
115 TRACE("(%p, %p, %p)\n", iface
, piNewTrigger
, ppTrigger
);
116 return TaskTriggerConstructor((LPVOID
*)ppTrigger
);
119 static HRESULT WINAPI
MSTASK_ITask_DeleteTrigger(
123 FIXME("(%p, %d): stub\n", iface
, iTrigger
);
127 static HRESULT WINAPI
MSTASK_ITask_GetTriggerCount(
131 FIXME("(%p, %p): stub\n", iface
, plCount
);
135 static HRESULT WINAPI
MSTASK_ITask_GetTrigger(
138 ITaskTrigger
**ppTrigger
)
140 FIXME("(%p, %d, %p): stub\n", iface
, iTrigger
, ppTrigger
);
144 static HRESULT WINAPI
MSTASK_ITask_GetTriggerString(
147 LPWSTR
*ppwszTrigger
)
149 FIXME("(%p, %d, %p): stub\n", iface
, iTrigger
, ppwszTrigger
);
153 static HRESULT WINAPI
MSTASK_ITask_GetRunTimes(
155 const LPSYSTEMTIME pstBegin
,
156 const LPSYSTEMTIME pstEnd
,
158 LPSYSTEMTIME
*rgstTaskTimes
)
160 FIXME("(%p, %p, %p, %p, %p): stub\n", iface
, pstBegin
, pstEnd
, pCount
,
165 static HRESULT WINAPI
MSTASK_ITask_GetNextRunTime(
167 SYSTEMTIME
*pstNextRun
)
169 FIXME("(%p, %p): stub\n", iface
, pstNextRun
);
173 static HRESULT WINAPI
MSTASK_ITask_SetIdleWait(
176 WORD wDeadlineMinutes
)
178 FIXME("(%p, %d, %d): stub\n", iface
, wIdleMinutes
, wDeadlineMinutes
);
182 static HRESULT WINAPI
MSTASK_ITask_GetIdleWait(
185 WORD
*pwDeadlineMinutes
)
187 FIXME("(%p, %p, %p): stub\n", iface
, pwIdleMinutes
, pwDeadlineMinutes
);
191 static HRESULT WINAPI
MSTASK_ITask_Run(
194 FIXME("(%p): stub\n", iface
);
198 static HRESULT WINAPI
MSTASK_ITask_Terminate(
201 FIXME("(%p): stub\n", iface
);
205 static HRESULT WINAPI
MSTASK_ITask_EditWorkItem(
210 FIXME("(%p, %p, %d): stub\n", iface
, hParent
, dwReserved
);
214 static HRESULT WINAPI
MSTASK_ITask_GetMostRecentRunTime(
216 SYSTEMTIME
*pstLastRun
)
218 FIXME("(%p, %p): stub\n", iface
, pstLastRun
);
222 static HRESULT WINAPI
MSTASK_ITask_GetStatus(
226 FIXME("(%p, %p): stub\n", iface
, phrStatus
);
230 static HRESULT WINAPI
MSTASK_ITask_GetExitCode(
234 FIXME("(%p, %p): stub\n", iface
, pdwExitCode
);
238 static HRESULT WINAPI
MSTASK_ITask_SetComment(
243 TaskImpl
*This
= impl_from_ITask(iface
);
246 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszComment
));
249 if (pwszComment
[0] == 0)
251 HeapFree(GetProcessHeap(), 0, This
->comment
);
252 This
->comment
= NULL
;
256 /* Set to pwszComment */
257 n
= (lstrlenW(pwszComment
) + 1);
258 tmp_comment
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
260 return E_OUTOFMEMORY
;
261 lstrcpyW(tmp_comment
, pwszComment
);
262 HeapFree(GetProcessHeap(), 0, This
->comment
);
263 This
->comment
= tmp_comment
;
268 static HRESULT WINAPI
MSTASK_ITask_GetComment(
270 LPWSTR
*ppwszComment
)
273 TaskImpl
*This
= impl_from_ITask(iface
);
275 TRACE("(%p, %p)\n", iface
, ppwszComment
);
277 n
= This
->comment
? lstrlenW(This
->comment
) + 1 : 1;
278 *ppwszComment
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
280 return E_OUTOFMEMORY
;
283 *ppwszComment
[0] = 0;
285 lstrcpyW(*ppwszComment
, This
->comment
);
290 static HRESULT WINAPI
MSTASK_ITask_SetCreator(
294 FIXME("(%p, %p): stub\n", iface
, pwszCreator
);
298 static HRESULT WINAPI
MSTASK_ITask_GetCreator(
300 LPWSTR
*ppwszCreator
)
302 FIXME("(%p, %p): stub\n", iface
, ppwszCreator
);
306 static HRESULT WINAPI
MSTASK_ITask_SetWorkItemData(
311 FIXME("(%p, %d, %p): stub\n", iface
, cBytes
, rgbData
);
315 static HRESULT WINAPI
MSTASK_ITask_GetWorkItemData(
320 FIXME("(%p, %p, %p): stub\n", iface
, pcBytes
, ppBytes
);
324 static HRESULT WINAPI
MSTASK_ITask_SetErrorRetryCount(
328 FIXME("(%p, %d): stub\n", iface
, wRetryCount
);
332 static HRESULT WINAPI
MSTASK_ITask_GetErrorRetryCount(
336 FIXME("(%p, %p): stub\n", iface
, pwRetryCount
);
340 static HRESULT WINAPI
MSTASK_ITask_SetErrorRetryInterval(
344 FIXME("(%p, %d): stub\n", iface
, wRetryInterval
);
348 static HRESULT WINAPI
MSTASK_ITask_GetErrorRetryInterval(
350 WORD
*pwRetryInterval
)
352 FIXME("(%p, %p): stub\n", iface
, pwRetryInterval
);
356 static HRESULT WINAPI
MSTASK_ITask_SetFlags(
360 FIXME("(%p, 0x%08x): stub\n", iface
, dwFlags
);
364 static HRESULT WINAPI
MSTASK_ITask_GetFlags(
368 FIXME("(%p, %p): stub\n", iface
, pdwFlags
);
372 static HRESULT WINAPI
MSTASK_ITask_SetAccountInformation(
374 LPCWSTR pwszAccountName
,
375 LPCWSTR pwszPassword
)
378 TaskImpl
*This
= impl_from_ITask(iface
);
379 LPWSTR tmp_account_name
;
381 TRACE("(%p, %s, %s): partial stub\n", iface
, debugstr_w(pwszAccountName
),
382 debugstr_w(pwszPassword
));
385 FIXME("Partial stub ignores passwords\n");
387 n
= (lstrlenW(pwszAccountName
) + 1);
388 tmp_account_name
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
389 if (!tmp_account_name
)
390 return E_OUTOFMEMORY
;
391 lstrcpyW(tmp_account_name
, pwszAccountName
);
392 HeapFree(GetProcessHeap(), 0, This
->accountName
);
393 This
->accountName
= tmp_account_name
;
397 static HRESULT WINAPI
MSTASK_ITask_GetAccountInformation(
399 LPWSTR
*ppwszAccountName
)
402 TaskImpl
*This
= impl_from_ITask(iface
);
404 TRACE("(%p, %p): partial stub\n", iface
, ppwszAccountName
);
406 /* This implements the WinXP behavior when accountName has not yet
407 * set. Win2K behaves differently, returning SCHED_E_CANNOT_OPEN_TASK */
408 if (!This
->accountName
)
409 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
411 n
= (lstrlenW(This
->accountName
) + 1);
412 *ppwszAccountName
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
413 if (!*ppwszAccountName
)
414 return E_OUTOFMEMORY
;
415 lstrcpyW(*ppwszAccountName
, This
->accountName
);
419 static HRESULT WINAPI
MSTASK_ITask_SetApplicationName(
421 LPCWSTR pwszApplicationName
)
424 TaskImpl
*This
= impl_from_ITask(iface
);
427 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszApplicationName
));
429 /* Empty application name */
430 if (pwszApplicationName
[0] == 0)
432 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
433 This
->applicationName
= NULL
;
437 /* Attempt to set pwszApplicationName to a path resolved application name */
438 n
= SearchPathW(NULL
, pwszApplicationName
, NULL
, 0, NULL
, NULL
);
441 tmp_name
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
443 return E_OUTOFMEMORY
;
444 n
= SearchPathW(NULL
, pwszApplicationName
, NULL
, n
, tmp_name
, NULL
);
447 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
448 This
->applicationName
= tmp_name
;
452 HeapFree(GetProcessHeap(), 0, tmp_name
);
455 /* If unable to path resolve name, simply set to pwszApplicationName */
456 n
= (lstrlenW(pwszApplicationName
) + 1);
457 tmp_name
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
459 return E_OUTOFMEMORY
;
460 lstrcpyW(tmp_name
, pwszApplicationName
);
461 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
462 This
->applicationName
= tmp_name
;
466 static HRESULT WINAPI
MSTASK_ITask_GetApplicationName(
468 LPWSTR
*ppwszApplicationName
)
471 TaskImpl
*This
= impl_from_ITask(iface
);
473 TRACE("(%p, %p)\n", iface
, ppwszApplicationName
);
475 n
= This
->applicationName
? lstrlenW(This
->applicationName
) + 1 : 1;
476 *ppwszApplicationName
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
477 if (!*ppwszApplicationName
)
478 return E_OUTOFMEMORY
;
480 if (!This
->applicationName
)
481 *ppwszApplicationName
[0] = 0;
483 lstrcpyW(*ppwszApplicationName
, This
->applicationName
);
488 static HRESULT WINAPI
MSTASK_ITask_SetParameters(
490 LPCWSTR pwszParameters
)
493 TaskImpl
*This
= impl_from_ITask(iface
);
494 LPWSTR tmp_parameters
;
496 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszParameters
));
498 /* Empty parameter list */
499 if (pwszParameters
[0] == 0)
501 HeapFree(GetProcessHeap(), 0, This
->parameters
);
502 This
->parameters
= NULL
;
506 /* Set to pwszParameters */
507 n
= (lstrlenW(pwszParameters
) + 1);
508 tmp_parameters
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
510 return E_OUTOFMEMORY
;
511 lstrcpyW(tmp_parameters
, pwszParameters
);
512 HeapFree(GetProcessHeap(), 0, This
->parameters
);
513 This
->parameters
= tmp_parameters
;
517 static HRESULT WINAPI
MSTASK_ITask_GetParameters(
519 LPWSTR
*ppwszParameters
)
522 TaskImpl
*This
= impl_from_ITask(iface
);
524 TRACE("(%p, %p)\n", iface
, ppwszParameters
);
526 n
= This
->parameters
? lstrlenW(This
->parameters
) + 1 : 1;
527 *ppwszParameters
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
528 if (!*ppwszParameters
)
529 return E_OUTOFMEMORY
;
531 if (!This
->parameters
)
532 *ppwszParameters
[0] = 0;
534 lstrcpyW(*ppwszParameters
, This
->parameters
);
539 static HRESULT WINAPI
MSTASK_ITask_SetWorkingDirectory(
541 LPCWSTR pwszWorkingDirectory
)
543 FIXME("(%p, %s): stub\n", iface
, debugstr_w(pwszWorkingDirectory
));
547 static HRESULT WINAPI
MSTASK_ITask_GetWorkingDirectory(
549 LPWSTR
*ppwszWorkingDirectory
)
551 FIXME("(%p, %p): stub\n", iface
, ppwszWorkingDirectory
);
555 static HRESULT WINAPI
MSTASK_ITask_SetPriority(
559 FIXME("(%p, 0x%08x): stub\n", iface
, dwPriority
);
563 static HRESULT WINAPI
MSTASK_ITask_GetPriority(
567 FIXME("(%p, %p): stub\n", iface
, pdwPriority
);
571 static HRESULT WINAPI
MSTASK_ITask_SetTaskFlags(
575 FIXME("(%p, 0x%08x): stub\n", iface
, dwFlags
);
579 static HRESULT WINAPI
MSTASK_ITask_GetTaskFlags(
583 FIXME("(%p, %p): stub\n", iface
, pdwFlags
);
587 static HRESULT WINAPI
MSTASK_ITask_SetMaxRunTime(
591 TaskImpl
*This
= impl_from_ITask(iface
);
593 TRACE("(%p, %d)\n", iface
, dwMaxRunTime
);
595 This
->maxRunTime
= dwMaxRunTime
;
599 static HRESULT WINAPI
MSTASK_ITask_GetMaxRunTime(
601 DWORD
*pdwMaxRunTime
)
603 TaskImpl
*This
= impl_from_ITask(iface
);
605 TRACE("(%p, %p)\n", iface
, pdwMaxRunTime
);
607 *pdwMaxRunTime
= This
->maxRunTime
;
611 static HRESULT WINAPI
MSTASK_IPersistFile_QueryInterface(
616 TaskImpl
*This
= impl_from_IPersistFile(iface
);
617 TRACE("(%p, %s, %p)\n", iface
, debugstr_guid(riid
), ppvObject
);
618 return ITask_QueryInterface(&This
->ITask_iface
, riid
, ppvObject
);
621 static ULONG WINAPI
MSTASK_IPersistFile_AddRef(
624 TaskImpl
*This
= impl_from_IPersistFile(iface
);
627 ref
= InterlockedIncrement(&This
->ref
);
631 static ULONG WINAPI
MSTASK_IPersistFile_Release(
634 TaskImpl
*This
= impl_from_IPersistFile(iface
);
637 ref
= InterlockedDecrement(&This
->ref
);
639 TaskDestructor(This
);
643 static HRESULT WINAPI
MSTASK_IPersistFile_GetClassID(
647 FIXME("(%p, %p): stub\n", iface
, pClassID
);
651 static HRESULT WINAPI
MSTASK_IPersistFile_IsDirty(
654 FIXME("(%p): stub\n", iface
);
658 static HRESULT WINAPI
MSTASK_IPersistFile_Load(
660 LPCOLESTR pszFileName
,
663 FIXME("(%p, %p, 0x%08x): stub\n", iface
, pszFileName
, dwMode
);
667 static HRESULT WINAPI
MSTASK_IPersistFile_Save(
669 LPCOLESTR pszFileName
,
672 FIXME("(%p, %p, %d): stub\n", iface
, pszFileName
, fRemember
);
673 WARN("Returning S_OK but not writing to disk: %s %d\n",
674 debugstr_w(pszFileName
), fRemember
);
678 static HRESULT WINAPI
MSTASK_IPersistFile_SaveCompleted(
680 LPCOLESTR pszFileName
)
682 FIXME("(%p, %p): stub\n", iface
, pszFileName
);
686 static HRESULT WINAPI
MSTASK_IPersistFile_GetCurFile(
688 LPOLESTR
*ppszFileName
)
690 FIXME("(%p, %p): stub\n", iface
, ppszFileName
);
695 static const ITaskVtbl MSTASK_ITaskVtbl
=
697 MSTASK_ITask_QueryInterface
,
699 MSTASK_ITask_Release
,
700 MSTASK_ITask_CreateTrigger
,
701 MSTASK_ITask_DeleteTrigger
,
702 MSTASK_ITask_GetTriggerCount
,
703 MSTASK_ITask_GetTrigger
,
704 MSTASK_ITask_GetTriggerString
,
705 MSTASK_ITask_GetRunTimes
,
706 MSTASK_ITask_GetNextRunTime
,
707 MSTASK_ITask_SetIdleWait
,
708 MSTASK_ITask_GetIdleWait
,
710 MSTASK_ITask_Terminate
,
711 MSTASK_ITask_EditWorkItem
,
712 MSTASK_ITask_GetMostRecentRunTime
,
713 MSTASK_ITask_GetStatus
,
714 MSTASK_ITask_GetExitCode
,
715 MSTASK_ITask_SetComment
,
716 MSTASK_ITask_GetComment
,
717 MSTASK_ITask_SetCreator
,
718 MSTASK_ITask_GetCreator
,
719 MSTASK_ITask_SetWorkItemData
,
720 MSTASK_ITask_GetWorkItemData
,
721 MSTASK_ITask_SetErrorRetryCount
,
722 MSTASK_ITask_GetErrorRetryCount
,
723 MSTASK_ITask_SetErrorRetryInterval
,
724 MSTASK_ITask_GetErrorRetryInterval
,
725 MSTASK_ITask_SetFlags
,
726 MSTASK_ITask_GetFlags
,
727 MSTASK_ITask_SetAccountInformation
,
728 MSTASK_ITask_GetAccountInformation
,
729 MSTASK_ITask_SetApplicationName
,
730 MSTASK_ITask_GetApplicationName
,
731 MSTASK_ITask_SetParameters
,
732 MSTASK_ITask_GetParameters
,
733 MSTASK_ITask_SetWorkingDirectory
,
734 MSTASK_ITask_GetWorkingDirectory
,
735 MSTASK_ITask_SetPriority
,
736 MSTASK_ITask_GetPriority
,
737 MSTASK_ITask_SetTaskFlags
,
738 MSTASK_ITask_GetTaskFlags
,
739 MSTASK_ITask_SetMaxRunTime
,
740 MSTASK_ITask_GetMaxRunTime
743 static const IPersistFileVtbl MSTASK_IPersistFileVtbl
=
745 MSTASK_IPersistFile_QueryInterface
,
746 MSTASK_IPersistFile_AddRef
,
747 MSTASK_IPersistFile_Release
,
748 MSTASK_IPersistFile_GetClassID
,
749 MSTASK_IPersistFile_IsDirty
,
750 MSTASK_IPersistFile_Load
,
751 MSTASK_IPersistFile_Save
,
752 MSTASK_IPersistFile_SaveCompleted
,
753 MSTASK_IPersistFile_GetCurFile
756 HRESULT
TaskConstructor(LPCWSTR pwszTaskName
, LPVOID
*ppObj
)
761 TRACE("(%s, %p)\n", debugstr_w(pwszTaskName
), ppObj
);
763 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
765 return E_OUTOFMEMORY
;
767 This
->ITask_iface
.lpVtbl
= &MSTASK_ITaskVtbl
;
768 This
->IPersistFile_iface
.lpVtbl
= &MSTASK_IPersistFileVtbl
;
770 n
= (lstrlenW(pwszTaskName
) + 1) * sizeof(WCHAR
);
771 This
->taskName
= HeapAlloc(GetProcessHeap(), 0, n
);
774 HeapFree(GetProcessHeap(), 0, This
);
775 return E_OUTOFMEMORY
;
777 lstrcpyW(This
->taskName
, pwszTaskName
);
778 This
->applicationName
= NULL
;
779 This
->parameters
= NULL
;
780 This
->comment
= NULL
;
781 This
->accountName
= NULL
;
783 /* Default time is 3 days = 259200000 ms */
784 This
->maxRunTime
= 259200000;
786 *ppObj
= &This
->ITask_iface
;
787 InterlockedIncrement(&dll_ref
);