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