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"
24 IPersistFile IPersistFile_iface
;
27 LPWSTR applicationName
;
34 static inline TaskImpl
*impl_from_ITask(ITask
*iface
)
36 return CONTAINING_RECORD(iface
, TaskImpl
, ITask_iface
);
39 static inline TaskImpl
*impl_from_IPersistFile( IPersistFile
*iface
)
41 return CONTAINING_RECORD(iface
, TaskImpl
, IPersistFile_iface
);
44 static void TaskDestructor(TaskImpl
*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
);
55 static HRESULT WINAPI
MSTASK_ITask_QueryInterface(
60 TaskImpl
* This
= impl_from_ITask(iface
);
62 TRACE("IID: %s\n", debugstr_guid(riid
));
63 if (ppvObject
== NULL
)
66 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
67 IsEqualGUID(riid
, &IID_ITask
))
69 *ppvObject
= &This
->ITask_iface
;
73 else if (IsEqualGUID(riid
, &IID_IPersistFile
))
75 *ppvObject
= &This
->IPersistFile_iface
;
80 WARN("Unknown interface: %s\n", debugstr_guid(riid
));
85 static ULONG WINAPI
MSTASK_ITask_AddRef(
88 TaskImpl
*This
= impl_from_ITask(iface
);
91 ref
= InterlockedIncrement(&This
->ref
);
95 static ULONG WINAPI
MSTASK_ITask_Release(
98 TaskImpl
* This
= impl_from_ITask(iface
);
101 ref
= InterlockedDecrement(&This
->ref
);
103 TaskDestructor(This
);
107 static HRESULT WINAPI
MSTASK_ITask_CreateTrigger(
110 ITaskTrigger
**ppTrigger
)
112 TRACE("(%p, %p, %p)\n", iface
, piNewTrigger
, ppTrigger
);
113 return TaskTriggerConstructor((LPVOID
*)ppTrigger
);
116 static HRESULT WINAPI
MSTASK_ITask_DeleteTrigger(
120 FIXME("(%p, %d): stub\n", iface
, iTrigger
);
124 static HRESULT WINAPI
MSTASK_ITask_GetTriggerCount(
128 FIXME("(%p, %p): stub\n", iface
, plCount
);
132 static HRESULT WINAPI
MSTASK_ITask_GetTrigger(
135 ITaskTrigger
**ppTrigger
)
137 FIXME("(%p, %d, %p): stub\n", iface
, iTrigger
, ppTrigger
);
141 static HRESULT WINAPI
MSTASK_ITask_GetTriggerString(
144 LPWSTR
*ppwszTrigger
)
146 FIXME("(%p, %d, %p): stub\n", iface
, iTrigger
, ppwszTrigger
);
150 static HRESULT WINAPI
MSTASK_ITask_GetRunTimes(
152 const LPSYSTEMTIME pstBegin
,
153 const LPSYSTEMTIME pstEnd
,
155 LPSYSTEMTIME
*rgstTaskTimes
)
157 FIXME("(%p, %p, %p, %p, %p): stub\n", iface
, pstBegin
, pstEnd
, pCount
,
162 static HRESULT WINAPI
MSTASK_ITask_GetNextRunTime(
164 SYSTEMTIME
*pstNextRun
)
166 FIXME("(%p, %p): stub\n", iface
, pstNextRun
);
170 static HRESULT WINAPI
MSTASK_ITask_SetIdleWait(
173 WORD wDeadlineMinutes
)
175 FIXME("(%p, %d, %d): stub\n", iface
, wIdleMinutes
, wDeadlineMinutes
);
179 static HRESULT WINAPI
MSTASK_ITask_GetIdleWait(
182 WORD
*pwDeadlineMinutes
)
184 FIXME("(%p, %p, %p): stub\n", iface
, pwIdleMinutes
, pwDeadlineMinutes
);
188 static HRESULT WINAPI
MSTASK_ITask_Run(
191 FIXME("(%p): stub\n", iface
);
195 static HRESULT WINAPI
MSTASK_ITask_Terminate(
198 FIXME("(%p): stub\n", iface
);
202 static HRESULT WINAPI
MSTASK_ITask_EditWorkItem(
207 FIXME("(%p, %p, %d): stub\n", iface
, hParent
, dwReserved
);
211 static HRESULT WINAPI
MSTASK_ITask_GetMostRecentRunTime(
213 SYSTEMTIME
*pstLastRun
)
215 FIXME("(%p, %p): stub\n", iface
, pstLastRun
);
219 static HRESULT WINAPI
MSTASK_ITask_GetStatus(
223 FIXME("(%p, %p): stub\n", iface
, phrStatus
);
227 static HRESULT WINAPI
MSTASK_ITask_GetExitCode(
231 FIXME("(%p, %p): stub\n", iface
, pdwExitCode
);
235 static HRESULT WINAPI
MSTASK_ITask_SetComment(
240 TaskImpl
*This
= impl_from_ITask(iface
);
243 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszComment
));
246 if (pwszComment
[0] == 0)
248 HeapFree(GetProcessHeap(), 0, This
->comment
);
249 This
->comment
= NULL
;
253 /* Set to pwszComment */
254 n
= (lstrlenW(pwszComment
) + 1);
255 tmp_comment
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
257 return E_OUTOFMEMORY
;
258 lstrcpyW(tmp_comment
, pwszComment
);
259 HeapFree(GetProcessHeap(), 0, This
->comment
);
260 This
->comment
= tmp_comment
;
265 static HRESULT WINAPI
MSTASK_ITask_GetComment(
267 LPWSTR
*ppwszComment
)
270 TaskImpl
*This
= impl_from_ITask(iface
);
272 TRACE("(%p, %p)\n", iface
, ppwszComment
);
274 n
= This
->comment
? lstrlenW(This
->comment
) + 1 : 1;
275 *ppwszComment
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
277 return E_OUTOFMEMORY
;
280 *ppwszComment
[0] = 0;
282 lstrcpyW(*ppwszComment
, This
->comment
);
287 static HRESULT WINAPI
MSTASK_ITask_SetCreator(
291 FIXME("(%p, %p): stub\n", iface
, pwszCreator
);
295 static HRESULT WINAPI
MSTASK_ITask_GetCreator(
297 LPWSTR
*ppwszCreator
)
299 FIXME("(%p, %p): stub\n", iface
, ppwszCreator
);
303 static HRESULT WINAPI
MSTASK_ITask_SetWorkItemData(
308 FIXME("(%p, %d, %p): stub\n", iface
, cBytes
, rgbData
);
312 static HRESULT WINAPI
MSTASK_ITask_GetWorkItemData(
317 FIXME("(%p, %p, %p): stub\n", iface
, pcBytes
, ppBytes
);
321 static HRESULT WINAPI
MSTASK_ITask_SetErrorRetryCount(
325 FIXME("(%p, %d): stub\n", iface
, wRetryCount
);
329 static HRESULT WINAPI
MSTASK_ITask_GetErrorRetryCount(
333 FIXME("(%p, %p): stub\n", iface
, pwRetryCount
);
337 static HRESULT WINAPI
MSTASK_ITask_SetErrorRetryInterval(
341 FIXME("(%p, %d): stub\n", iface
, wRetryInterval
);
345 static HRESULT WINAPI
MSTASK_ITask_GetErrorRetryInterval(
347 WORD
*pwRetryInterval
)
349 FIXME("(%p, %p): stub\n", iface
, pwRetryInterval
);
353 static HRESULT WINAPI
MSTASK_ITask_SetFlags(
357 FIXME("(%p, 0x%08x): stub\n", iface
, dwFlags
);
361 static HRESULT WINAPI
MSTASK_ITask_GetFlags(
365 FIXME("(%p, %p): stub\n", iface
, pdwFlags
);
369 static HRESULT WINAPI
MSTASK_ITask_SetAccountInformation(
371 LPCWSTR pwszAccountName
,
372 LPCWSTR pwszPassword
)
375 TaskImpl
*This
= impl_from_ITask(iface
);
376 LPWSTR tmp_account_name
;
378 TRACE("(%p, %s, %s): partial stub\n", iface
, debugstr_w(pwszAccountName
),
379 debugstr_w(pwszPassword
));
382 FIXME("Partial stub ignores passwords\n");
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
;
394 static HRESULT WINAPI
MSTASK_ITask_GetAccountInformation(
396 LPWSTR
*ppwszAccountName
)
399 TaskImpl
*This
= impl_from_ITask(iface
);
401 TRACE("(%p, %p): partial stub\n", iface
, ppwszAccountName
);
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
);
408 n
= (lstrlenW(This
->accountName
) + 1);
409 *ppwszAccountName
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
410 if (!*ppwszAccountName
)
411 return E_OUTOFMEMORY
;
412 lstrcpyW(*ppwszAccountName
, This
->accountName
);
416 static HRESULT WINAPI
MSTASK_ITask_SetApplicationName(
418 LPCWSTR pwszApplicationName
)
421 TaskImpl
*This
= impl_from_ITask(iface
);
424 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszApplicationName
));
426 /* Empty application name */
427 if (pwszApplicationName
[0] == 0)
429 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
430 This
->applicationName
= NULL
;
434 /* Attempt to set pwszApplicationName to a path resolved application name */
435 n
= SearchPathW(NULL
, pwszApplicationName
, NULL
, 0, NULL
, NULL
);
438 tmp_name
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
440 return E_OUTOFMEMORY
;
441 n
= SearchPathW(NULL
, pwszApplicationName
, NULL
, n
, tmp_name
, NULL
);
444 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
445 This
->applicationName
= tmp_name
;
449 HeapFree(GetProcessHeap(), 0, tmp_name
);
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
));
456 return E_OUTOFMEMORY
;
457 lstrcpyW(tmp_name
, pwszApplicationName
);
458 HeapFree(GetProcessHeap(), 0, This
->applicationName
);
459 This
->applicationName
= tmp_name
;
463 static HRESULT WINAPI
MSTASK_ITask_GetApplicationName(
465 LPWSTR
*ppwszApplicationName
)
468 TaskImpl
*This
= impl_from_ITask(iface
);
470 TRACE("(%p, %p)\n", iface
, ppwszApplicationName
);
472 n
= This
->applicationName
? lstrlenW(This
->applicationName
) + 1 : 1;
473 *ppwszApplicationName
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
474 if (!*ppwszApplicationName
)
475 return E_OUTOFMEMORY
;
477 if (!This
->applicationName
)
478 *ppwszApplicationName
[0] = 0;
480 lstrcpyW(*ppwszApplicationName
, This
->applicationName
);
485 static HRESULT WINAPI
MSTASK_ITask_SetParameters(
487 LPCWSTR pwszParameters
)
490 TaskImpl
*This
= impl_from_ITask(iface
);
491 LPWSTR tmp_parameters
;
493 TRACE("(%p, %s)\n", iface
, debugstr_w(pwszParameters
));
495 /* Empty parameter list */
496 if (pwszParameters
[0] == 0)
498 HeapFree(GetProcessHeap(), 0, This
->parameters
);
499 This
->parameters
= NULL
;
503 /* Set to pwszParameters */
504 n
= (lstrlenW(pwszParameters
) + 1);
505 tmp_parameters
= HeapAlloc(GetProcessHeap(), 0, n
* sizeof(WCHAR
));
507 return E_OUTOFMEMORY
;
508 lstrcpyW(tmp_parameters
, pwszParameters
);
509 HeapFree(GetProcessHeap(), 0, This
->parameters
);
510 This
->parameters
= tmp_parameters
;
514 static HRESULT WINAPI
MSTASK_ITask_GetParameters(
516 LPWSTR
*ppwszParameters
)
519 TaskImpl
*This
= impl_from_ITask(iface
);
521 TRACE("(%p, %p)\n", iface
, ppwszParameters
);
523 n
= This
->parameters
? lstrlenW(This
->parameters
) + 1 : 1;
524 *ppwszParameters
= CoTaskMemAlloc(n
* sizeof(WCHAR
));
525 if (!*ppwszParameters
)
526 return E_OUTOFMEMORY
;
528 if (!This
->parameters
)
529 *ppwszParameters
[0] = 0;
531 lstrcpyW(*ppwszParameters
, This
->parameters
);
536 static HRESULT WINAPI
MSTASK_ITask_SetWorkingDirectory(
538 LPCWSTR pwszWorkingDirectory
)
540 FIXME("(%p, %s): stub\n", iface
, debugstr_w(pwszWorkingDirectory
));
544 static HRESULT WINAPI
MSTASK_ITask_GetWorkingDirectory(
546 LPWSTR
*ppwszWorkingDirectory
)
548 FIXME("(%p, %p): stub\n", iface
, ppwszWorkingDirectory
);
552 static HRESULT WINAPI
MSTASK_ITask_SetPriority(
556 FIXME("(%p, 0x%08x): stub\n", iface
, dwPriority
);
560 static HRESULT WINAPI
MSTASK_ITask_GetPriority(
564 FIXME("(%p, %p): stub\n", iface
, pdwPriority
);
568 static HRESULT WINAPI
MSTASK_ITask_SetTaskFlags(
572 FIXME("(%p, 0x%08x): stub\n", iface
, dwFlags
);
576 static HRESULT WINAPI
MSTASK_ITask_GetTaskFlags(
580 FIXME("(%p, %p): stub\n", iface
, pdwFlags
);
584 static HRESULT WINAPI
MSTASK_ITask_SetMaxRunTime(
588 TaskImpl
*This
= impl_from_ITask(iface
);
590 TRACE("(%p, %d)\n", iface
, dwMaxRunTime
);
592 This
->maxRunTime
= dwMaxRunTime
;
596 static HRESULT WINAPI
MSTASK_ITask_GetMaxRunTime(
598 DWORD
*pdwMaxRunTime
)
600 TaskImpl
*This
= impl_from_ITask(iface
);
602 TRACE("(%p, %p)\n", iface
, pdwMaxRunTime
);
604 *pdwMaxRunTime
= This
->maxRunTime
;
608 static HRESULT WINAPI
MSTASK_IPersistFile_QueryInterface(
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
);
618 static ULONG WINAPI
MSTASK_IPersistFile_AddRef(
621 TaskImpl
*This
= impl_from_IPersistFile(iface
);
624 ref
= InterlockedIncrement(&This
->ref
);
628 static ULONG WINAPI
MSTASK_IPersistFile_Release(
631 TaskImpl
*This
= impl_from_IPersistFile(iface
);
634 ref
= InterlockedDecrement(&This
->ref
);
636 TaskDestructor(This
);
640 static HRESULT WINAPI
MSTASK_IPersistFile_GetClassID(
644 FIXME("(%p, %p): stub\n", iface
, pClassID
);
648 static HRESULT WINAPI
MSTASK_IPersistFile_IsDirty(
651 FIXME("(%p): stub\n", iface
);
655 static HRESULT WINAPI
MSTASK_IPersistFile_Load(
657 LPCOLESTR pszFileName
,
660 FIXME("(%p, %p, 0x%08x): stub\n", iface
, pszFileName
, dwMode
);
664 static HRESULT WINAPI
MSTASK_IPersistFile_Save(
666 LPCOLESTR pszFileName
,
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
);
675 static HRESULT WINAPI
MSTASK_IPersistFile_SaveCompleted(
677 LPCOLESTR pszFileName
)
679 FIXME("(%p, %p): stub\n", iface
, pszFileName
);
683 static HRESULT WINAPI
MSTASK_IPersistFile_GetCurFile(
685 LPOLESTR
*ppszFileName
)
687 FIXME("(%p, %p): stub\n", iface
, ppszFileName
);
692 static const ITaskVtbl MSTASK_ITaskVtbl
=
694 MSTASK_ITask_QueryInterface
,
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
,
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
740 static const IPersistFileVtbl MSTASK_IPersistFileVtbl
=
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
753 HRESULT
TaskConstructor(LPCWSTR pwszTaskName
, LPVOID
*ppObj
)
758 TRACE("(%s, %p)\n", debugstr_w(pwszTaskName
), ppObj
);
760 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
762 return E_OUTOFMEMORY
;
764 This
->ITask_iface
.lpVtbl
= &MSTASK_ITaskVtbl
;
765 This
->IPersistFile_iface
.lpVtbl
= &MSTASK_IPersistFileVtbl
;
767 n
= (lstrlenW(pwszTaskName
) + 1) * sizeof(WCHAR
);
768 This
->taskName
= HeapAlloc(GetProcessHeap(), 0, n
);
771 HeapFree(GetProcessHeap(), 0, This
);
772 return E_OUTOFMEMORY
;
774 lstrcpyW(This
->taskName
, pwszTaskName
);
775 This
->applicationName
= NULL
;
776 This
->parameters
= NULL
;
777 This
->comment
= NULL
;
778 This
->accountName
= NULL
;
780 /* Default time is 3 days = 259200000 ms */
781 This
->maxRunTime
= 259200000;
783 *ppObj
= &This
->ITask_iface
;
784 InterlockedIncrement(&dll_ref
);