mstask: Task PersistFile AddRef, QueryInterface, and Release.
[wine] / dlls / 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 #include "wine/debug.h"
21
22 WINE_DEFAULT_DEBUG_CHANNEL(mstask);
23
24 static inline TaskImpl *impl_from_IPersistFile( IPersistFile *iface )
25 {
26     return (TaskImpl*) ((char*)(iface) - FIELD_OFFSET(TaskImpl, persistVtbl));
27 }
28
29 static void TaskDestructor(TaskImpl *This)
30 {
31     TRACE("%p\n", This);
32     HeapFree(GetProcessHeap(), 0, This->taskName);
33     HeapFree(GetProcessHeap(), 0, This);
34     InterlockedDecrement(&dll_ref);
35 }
36
37 static HRESULT WINAPI MSTASK_ITask_QueryInterface(
38         ITask* iface,
39         REFIID riid,
40         void **ppvObject)
41 {
42     TaskImpl * This = (TaskImpl *)iface;
43
44     TRACE("IID: %s\n", debugstr_guid(riid));
45     if (ppvObject == NULL)
46         return E_POINTER;
47
48     if (IsEqualGUID(riid, &IID_IUnknown) ||
49             IsEqualGUID(riid, &IID_ITask))
50     {
51         *ppvObject = &This->lpVtbl;
52         ITask_AddRef(iface);
53         return S_OK;
54     }
55     else if (IsEqualGUID(riid, &IID_IPersistFile))
56     {
57         *ppvObject = &This->persistVtbl;
58         ITask_AddRef(iface);
59         return S_OK;
60     }
61
62     WARN("Unknown interface: %s\n", debugstr_guid(riid));
63     *ppvObject = NULL;
64     return E_NOINTERFACE;
65 }
66
67 static ULONG WINAPI MSTASK_ITask_AddRef(
68         ITask* iface)
69 {
70     TaskImpl *This = (TaskImpl *)iface;
71     ULONG ref;
72     TRACE("\n");
73     ref = InterlockedIncrement(&This->ref);
74     return ref;
75 }
76
77 static ULONG WINAPI MSTASK_ITask_Release(
78         ITask* iface)
79 {
80     TaskImpl * This = (TaskImpl *)iface;
81     ULONG ref;
82     TRACE("\n");
83     ref = InterlockedDecrement(&This->ref);
84     if (ref == 0)
85         TaskDestructor(This);
86     return ref;
87 }
88
89 static HRESULT WINAPI MSTASK_ITask_CreateTrigger(
90         ITask* iface,
91         WORD *piNewTrigger,
92         ITaskTrigger **ppTrigger)
93 {
94     FIXME("(%p, %p, %p): stub\n", iface, piNewTrigger, ppTrigger);
95     return E_NOTIMPL;
96 }
97
98 static HRESULT WINAPI MSTASK_ITask_DeleteTrigger(
99         ITask* iface,
100         WORD iTrigger)
101 {
102     FIXME("(%p, %d): stub\n", iface, iTrigger);
103     return E_NOTIMPL;
104 }
105
106 static HRESULT WINAPI MSTASK_ITask_GetTriggerCount(
107         ITask* iface,
108         WORD *plCount)
109 {
110     FIXME("(%p, %p): stub\n", iface, plCount);
111     return E_NOTIMPL;
112 }
113
114 static HRESULT WINAPI MSTASK_ITask_GetTrigger(
115         ITask* iface,
116         WORD iTrigger,
117         ITaskTrigger **ppTrigger)
118 {
119     FIXME("(%p, %d, %p): stub\n", iface, iTrigger, ppTrigger);
120     return E_NOTIMPL;
121 }
122
123 static HRESULT WINAPI MSTASK_ITask_GetTriggerString(
124         ITask* iface,
125         WORD iTrigger,
126         LPWSTR *ppwszTrigger)
127 {
128     FIXME("(%p, %d, %p): stub\n", iface, iTrigger, ppwszTrigger);
129     return E_NOTIMPL;
130 }
131
132 static HRESULT WINAPI MSTASK_ITask_GetRunTimes(
133         ITask* iface,
134         const LPSYSTEMTIME pstBegin,
135         const LPSYSTEMTIME pstEnd,
136         WORD *pCount,
137         LPSYSTEMTIME *rgstTaskTimes)
138 {
139     FIXME("(%p, %p, %p, %p, %p): stub\n", iface, pstBegin, pstEnd, pCount,
140             rgstTaskTimes);
141     return E_NOTIMPL;
142 }
143
144 static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(
145         ITask* iface,
146         SYSTEMTIME *pstNextRun)
147 {
148     FIXME("(%p, %p): stub\n", iface, pstNextRun);
149     return E_NOTIMPL;
150 }
151
152 static HRESULT WINAPI MSTASK_ITask_SetIdleWait(
153         ITask* iface,
154         WORD wIdleMinutes,
155         WORD wDeadlineMinutes)
156 {
157     FIXME("(%p, %d, %d): stub\n", iface, wIdleMinutes, wDeadlineMinutes);
158     return E_NOTIMPL;
159 }
160
161 static HRESULT WINAPI MSTASK_ITask_GetIdleWait(
162         ITask* iface,
163         WORD *pwIdleMinutes,
164         WORD *pwDeadlineMinutes)
165 {
166     FIXME("(%p, %p, %p): stub\n", iface, pwIdleMinutes, pwDeadlineMinutes);
167     return E_NOTIMPL;
168 }
169
170 static HRESULT WINAPI MSTASK_ITask_Run(
171         ITask* iface)
172 {
173     FIXME("(%p): stub\n", iface);
174     return E_NOTIMPL;
175 }
176
177 static HRESULT WINAPI MSTASK_ITask_Terminate(
178         ITask* iface)
179 {
180     FIXME("(%p): stub\n", iface);
181     return E_NOTIMPL;
182 }
183
184 static HRESULT WINAPI MSTASK_ITask_EditWorkItem(
185         ITask* iface,
186         HWND hParent,
187         DWORD dwReserved)
188 {
189     FIXME("(%p, %p, %d): stub\n", iface, hParent, dwReserved);
190     return E_NOTIMPL;
191 }
192
193 static HRESULT WINAPI MSTASK_ITask_GetMostRecentRunTime(
194         ITask* iface,
195         SYSTEMTIME *pstLastRun)
196 {
197     FIXME("(%p, %p): stub\n", iface, pstLastRun);
198     return E_NOTIMPL;
199 }
200
201 static HRESULT WINAPI MSTASK_ITask_GetStatus(
202         ITask* iface,
203         HRESULT *phrStatus)
204 {
205     FIXME("(%p, %p): stub\n", iface, phrStatus);
206     return E_NOTIMPL;
207 }
208
209 static HRESULT WINAPI MSTASK_ITask_GetExitCode(
210         ITask* iface,
211         DWORD *pdwExitCode)
212 {
213     FIXME("(%p, %p): stub\n", iface, pdwExitCode);
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI MSTASK_ITask_SetComment(
218         ITask* iface,
219         LPCWSTR pwszComment)
220 {
221     FIXME("(%p, %s): stub\n", iface, debugstr_w(pwszComment));
222     return E_NOTIMPL;
223 }
224
225 static HRESULT WINAPI MSTASK_ITask_GetComment(
226         ITask* iface,
227         LPWSTR *ppwszComment)
228 {
229     FIXME("(%p, %p): stub\n", iface, ppwszComment);
230     return E_NOTIMPL;
231 }
232
233 static HRESULT WINAPI MSTASK_ITask_SetCreator(
234         ITask* iface,
235         LPCWSTR pwszCreator)
236 {
237     FIXME("(%p, %p): stub\n", iface, pwszCreator);
238     return E_NOTIMPL;
239 }
240
241 static HRESULT WINAPI MSTASK_ITask_GetCreator(
242         ITask* iface,
243         LPWSTR *ppwszCreator)
244 {
245     FIXME("(%p, %p): stub\n", iface, ppwszCreator);
246     return E_NOTIMPL;
247 }
248
249 static HRESULT WINAPI MSTASK_ITask_SetWorkItemData(
250         ITask* iface,
251         WORD cBytes,
252         BYTE rgbData[])
253 {
254     FIXME("(%p, %d, %p): stub\n", iface, cBytes, rgbData);
255     return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI MSTASK_ITask_GetWorkItemData(
259         ITask* iface,
260         WORD *pcBytes,
261         BYTE **ppBytes)
262 {
263     FIXME("(%p, %p, %p): stub\n", iface, pcBytes, ppBytes);
264     return E_NOTIMPL;
265 }
266
267 static HRESULT WINAPI MSTASK_ITask_SetErrorRetryCount(
268         ITask* iface,
269         WORD wRetryCount)
270 {
271     FIXME("(%p, %d): stub\n", iface, wRetryCount);
272     return E_NOTIMPL;
273 }
274
275 static HRESULT WINAPI MSTASK_ITask_GetErrorRetryCount(
276         ITask* iface,
277         WORD *pwRetryCount)
278 {
279     FIXME("(%p, %p): stub\n", iface, pwRetryCount);
280     return E_NOTIMPL;
281 }
282
283 static HRESULT WINAPI MSTASK_ITask_SetErrorRetryInterval(
284         ITask* iface,
285         WORD wRetryInterval)
286 {
287     FIXME("(%p, %d): stub\n", iface, wRetryInterval);
288     return E_NOTIMPL;
289 }
290
291 static HRESULT WINAPI MSTASK_ITask_GetErrorRetryInterval(
292         ITask* iface,
293         WORD *pwRetryInterval)
294 {
295     FIXME("(%p, %p): stub\n", iface, pwRetryInterval);
296     return E_NOTIMPL;
297 }
298
299 static HRESULT WINAPI MSTASK_ITask_SetFlags(
300         ITask* iface,
301         DWORD dwFlags)
302 {
303     FIXME("(%p, 0x%08x): stub\n", iface, dwFlags);
304     return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI MSTASK_ITask_GetFlags(
308         ITask* iface,
309         DWORD *pdwFlags)
310 {
311     FIXME("(%p, %p): stub\n", iface, pdwFlags);
312     return E_NOTIMPL;
313 }
314
315 static HRESULT WINAPI MSTASK_ITask_SetAccountInformation(
316         ITask* iface,
317         LPCWSTR pwszAccountName,
318         LPCWSTR pwszPassword)
319 {
320     FIXME("(%p, %s, %s): stub\n", iface, debugstr_w(pwszAccountName),
321             debugstr_w(pwszPassword));
322     return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI MSTASK_ITask_GetAccountInformation(
326         ITask* iface,
327         LPWSTR *ppwszAccountName)
328 {
329     FIXME("(%p, %p): stub\n", iface, ppwszAccountName);
330     return E_NOTIMPL;
331 }
332
333 static HRESULT WINAPI MSTASK_ITask_SetApplicationName(
334         ITask* iface,
335         LPCWSTR pwszApplicationName)
336 {
337     DWORD n;
338     TaskImpl *This = (TaskImpl *)iface;
339     LPWSTR tmp_name;
340
341     TRACE("(%p, %s)\n", iface, debugstr_w(pwszApplicationName));
342
343     /* Empty application name */
344     if (pwszApplicationName[0] == 0)
345     {
346         HeapFree(GetProcessHeap(), 0, This->applicationName);
347         This->applicationName = NULL;
348         return S_OK;
349     }
350
351     /* Attempt to set pwszApplicationName to a path resolved application name */
352     n = SearchPathW(NULL, pwszApplicationName, NULL, 0, NULL, NULL);
353     if (n)
354     {
355         tmp_name = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
356         if (!tmp_name)
357             return E_OUTOFMEMORY;
358         n = SearchPathW(NULL, pwszApplicationName, NULL, n, tmp_name, NULL);
359         if (n)
360         {
361             HeapFree(GetProcessHeap(), 0, This->applicationName);
362             This->applicationName = tmp_name;
363             return S_OK;
364         }
365         else
366             HeapFree(GetProcessHeap(), 0, tmp_name);
367     }
368
369     /* If unable to path resolve name, simply set to pwszApplicationName */
370     n = (lstrlenW(pwszApplicationName) + 1);
371     tmp_name = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
372     if (!tmp_name)
373         return E_OUTOFMEMORY;
374     lstrcpyW(tmp_name, pwszApplicationName);
375     HeapFree(GetProcessHeap(), 0, This->applicationName);
376     This->applicationName = tmp_name;
377     return S_OK;
378 }
379
380 static HRESULT WINAPI MSTASK_ITask_GetApplicationName(
381         ITask* iface,
382         LPWSTR *ppwszApplicationName)
383 {
384     DWORD n;
385     TaskImpl *This = (TaskImpl *)iface;
386
387     TRACE("(%p, %p)\n", iface, ppwszApplicationName);
388
389     n = This->applicationName ? lstrlenW(This->applicationName) + 1 : 1;
390     *ppwszApplicationName = CoTaskMemAlloc(n * sizeof(WCHAR));
391     if (!*ppwszApplicationName)
392         return E_OUTOFMEMORY;
393
394     if (!This->applicationName)
395         *ppwszApplicationName[0] = 0;
396     else
397         lstrcpyW(*ppwszApplicationName, This->applicationName);
398
399     return S_OK;
400 }
401
402 static HRESULT WINAPI MSTASK_ITask_SetParameters(
403         ITask* iface,
404         LPCWSTR pwszParameters)
405 {
406     FIXME("(%p, %s): stub\n", iface, debugstr_w(pwszParameters));
407     return E_NOTIMPL;
408 }
409
410 static HRESULT WINAPI MSTASK_ITask_GetParameters(
411         ITask* iface,
412         LPWSTR *ppwszParameters)
413 {
414     FIXME("(%p, %p): stub\n", iface, ppwszParameters);
415     return E_NOTIMPL;
416 }
417
418 static HRESULT WINAPI MSTASK_ITask_SetWorkingDirectory(
419         ITask* iface,
420         LPCWSTR pwszWorkingDirectory)
421 {
422     FIXME("(%p, %s): stub\n", iface, debugstr_w(pwszWorkingDirectory));
423     return E_NOTIMPL;
424 }
425
426 static HRESULT WINAPI MSTASK_ITask_GetWorkingDirectory(
427         ITask* iface,
428         LPWSTR *ppwszWorkingDirectory)
429 {
430     FIXME("(%p, %p): stub\n", iface, ppwszWorkingDirectory);
431     return E_NOTIMPL;
432 }
433
434 static HRESULT WINAPI MSTASK_ITask_SetPriority(
435         ITask* iface,
436         DWORD dwPriority)
437 {
438     FIXME("(%p, 0x%08x): stub\n", iface, dwPriority);
439     return E_NOTIMPL;
440 }
441
442 static HRESULT WINAPI MSTASK_ITask_GetPriority(
443         ITask* iface,
444         DWORD *pdwPriority)
445 {
446     FIXME("(%p, %p): stub\n", iface, pdwPriority);
447     return E_NOTIMPL;
448 }
449
450 static HRESULT WINAPI MSTASK_ITask_SetTaskFlags(
451         ITask* iface,
452         DWORD dwFlags)
453 {
454     FIXME("(%p, 0x%08x): stub\n", iface, dwFlags);
455     return E_NOTIMPL;
456 }
457
458 static HRESULT WINAPI MSTASK_ITask_GetTaskFlags(
459         ITask* iface,
460         DWORD *pdwFlags)
461 {
462     FIXME("(%p, %p): stub\n", iface, pdwFlags);
463     return E_NOTIMPL;
464 }
465
466 static HRESULT WINAPI MSTASK_ITask_SetMaxRunTime(
467         ITask* iface,
468         DWORD dwMaxRunTime)
469 {
470     FIXME("(%p, %d): stub\n", iface, dwMaxRunTime);
471     return E_NOTIMPL;
472 }
473
474 static HRESULT WINAPI MSTASK_ITask_GetMaxRunTime(
475         ITask* iface,
476         DWORD *pdwMaxRunTime)
477 {
478     FIXME("(%p, %p): stub\n", iface, pdwMaxRunTime);
479     return E_NOTIMPL;
480 }
481
482 static HRESULT WINAPI MSTASK_IPersistFile_QueryInterface(
483         IPersistFile* iface,
484         REFIID riid,
485         void **ppvObject)
486 {
487     TaskImpl *This = impl_from_IPersistFile(iface);
488     TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), ppvObject);
489     return ITask_QueryInterface((ITask *) This, riid, ppvObject);
490 }
491
492 static ULONG WINAPI MSTASK_IPersistFile_AddRef(
493         IPersistFile* iface)
494 {
495     TaskImpl *This = impl_from_IPersistFile(iface);
496     ULONG ref;
497     TRACE("\n");
498     ref = InterlockedIncrement(&This->ref);
499     return ref;
500 }
501
502 static ULONG WINAPI MSTASK_IPersistFile_Release(
503         IPersistFile* iface)
504 {
505     TaskImpl *This = impl_from_IPersistFile(iface);
506     ULONG ref;
507     TRACE("\n");
508     ref = InterlockedDecrement(&This->ref);
509     if (ref == 0)
510         TaskDestructor(This);
511     return ref;
512 }
513
514 static HRESULT WINAPI MSTASK_IPersistFile_GetClassID(
515         IPersistFile* iface,
516         CLSID *pClassID)
517 {
518     FIXME("(%p, %p): stub\n", iface, pClassID);
519     return E_NOTIMPL;
520 }
521
522 static HRESULT WINAPI MSTASK_IPersistFile_IsDirty(
523         IPersistFile* iface)
524 {
525     FIXME("(%p): stub\n", iface);
526     return E_NOTIMPL;
527 }
528
529 static HRESULT WINAPI MSTASK_IPersistFile_Load(
530         IPersistFile* iface,
531         LPCOLESTR pszFileName,
532         DWORD dwMode)
533 {
534     FIXME("(%p, %p, 0x%08x): stub\n", iface, pszFileName, dwMode);
535     return E_NOTIMPL;
536 }
537
538 static HRESULT WINAPI MSTASK_IPersistFile_Save(
539         IPersistFile* iface,
540         LPCOLESTR pszFileName,
541         BOOL fRemember)
542 {
543     FIXME("(%p, %p, %d): stub\n", iface, pszFileName, fRemember);
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI MSTASK_IPersistFile_SaveCompleted(
548         IPersistFile* iface,
549         LPCOLESTR pszFileName)
550 {
551     FIXME("(%p, %p): stub\n", iface, pszFileName);
552     return E_NOTIMPL;
553 }
554
555 static HRESULT WINAPI MSTASK_IPersistFile_GetCurFile(
556         IPersistFile* iface,
557         LPOLESTR *ppszFileName)
558 {
559     FIXME("(%p, %p): stub\n", iface, ppszFileName);
560     return E_NOTIMPL;
561 }
562
563
564 static const ITaskVtbl MSTASK_ITaskVtbl =
565 {
566     MSTASK_ITask_QueryInterface,
567     MSTASK_ITask_AddRef,
568     MSTASK_ITask_Release,
569     MSTASK_ITask_CreateTrigger,
570     MSTASK_ITask_DeleteTrigger,
571     MSTASK_ITask_GetTriggerCount,
572     MSTASK_ITask_GetTrigger,
573     MSTASK_ITask_GetTriggerString,
574     MSTASK_ITask_GetRunTimes,
575     MSTASK_ITask_GetNextRunTime,
576     MSTASK_ITask_SetIdleWait,
577     MSTASK_ITask_GetIdleWait,
578     MSTASK_ITask_Run,
579     MSTASK_ITask_Terminate,
580     MSTASK_ITask_EditWorkItem,
581     MSTASK_ITask_GetMostRecentRunTime,
582     MSTASK_ITask_GetStatus,
583     MSTASK_ITask_GetExitCode,
584     MSTASK_ITask_SetComment,
585     MSTASK_ITask_GetComment,
586     MSTASK_ITask_SetCreator,
587     MSTASK_ITask_GetCreator,
588     MSTASK_ITask_SetWorkItemData,
589     MSTASK_ITask_GetWorkItemData,
590     MSTASK_ITask_SetErrorRetryCount,
591     MSTASK_ITask_GetErrorRetryCount,
592     MSTASK_ITask_SetErrorRetryInterval,
593     MSTASK_ITask_GetErrorRetryInterval,
594     MSTASK_ITask_SetFlags,
595     MSTASK_ITask_GetFlags,
596     MSTASK_ITask_SetAccountInformation,
597     MSTASK_ITask_GetAccountInformation,
598     MSTASK_ITask_SetApplicationName,
599     MSTASK_ITask_GetApplicationName,
600     MSTASK_ITask_SetParameters,
601     MSTASK_ITask_GetParameters,
602     MSTASK_ITask_SetWorkingDirectory,
603     MSTASK_ITask_GetWorkingDirectory,
604     MSTASK_ITask_SetPriority,
605     MSTASK_ITask_GetPriority,
606     MSTASK_ITask_SetTaskFlags,
607     MSTASK_ITask_GetTaskFlags,
608     MSTASK_ITask_SetMaxRunTime,
609     MSTASK_ITask_GetMaxRunTime
610 };
611
612 static const IPersistFileVtbl MSTASK_IPersistFileVtbl =
613 {
614     MSTASK_IPersistFile_QueryInterface,
615     MSTASK_IPersistFile_AddRef,
616     MSTASK_IPersistFile_Release,
617     MSTASK_IPersistFile_GetClassID,
618     MSTASK_IPersistFile_IsDirty,
619     MSTASK_IPersistFile_Load,
620     MSTASK_IPersistFile_Save,
621     MSTASK_IPersistFile_SaveCompleted,
622     MSTASK_IPersistFile_GetCurFile
623 };
624
625 HRESULT TaskConstructor(LPCWSTR pwszTaskName, LPVOID *ppObj)
626 {
627     TaskImpl *This;
628     int n;
629
630     TRACE("(%s, %p)\n", debugstr_w(pwszTaskName), ppObj);
631
632     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
633     if (!This)
634         return E_OUTOFMEMORY;
635
636     This->lpVtbl = &MSTASK_ITaskVtbl;
637     This->persistVtbl = &MSTASK_IPersistFileVtbl;
638     This->ref = 1;
639     n = (lstrlenW(pwszTaskName) + 1) * sizeof(WCHAR);
640     This->taskName = HeapAlloc(GetProcessHeap(), 0, n);
641     if (!This->taskName)
642     {
643         HeapFree(GetProcessHeap(), 0, This);
644         return E_OUTOFMEMORY;
645     }
646     lstrcpyW(This->taskName, pwszTaskName);
647     This->applicationName = NULL;
648
649     *ppObj = &This->lpVtbl;
650     InterlockedIncrement(&dll_ref);
651     return S_OK;
652 }