Testing under Windows revealed that task definition on disk should be created only when IPersistFile::Save() is called, and until that ITask should stay as a task description in memory.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/mstask/mstask_private.h | 15 ++++++++++++++- dlls/mstask/task.c | 37 ++++++++++--------------------------- dlls/mstask/task_scheduler.c | 14 +------------- 3 files changed, 25 insertions(+), 41 deletions(-)
diff --git a/dlls/mstask/mstask_private.h b/dlls/mstask/mstask_private.h index 511019ded6..038c6c84c1 100644 --- a/dlls/mstask/mstask_private.h +++ b/dlls/mstask/mstask_private.h @@ -19,6 +19,9 @@ #ifndef __MSTASK_PRIVATE_H__ #define __MSTASK_PRIVATE_H__
+#include "wine/heap.h" +#include "wine/unicode.h" + extern LONG dll_ref DECLSPEC_HIDDEN;
typedef struct ClassFactoryImpl ClassFactoryImpl; @@ -26,6 +29,16 @@ extern ClassFactoryImpl MSTASK_ClassFactory DECLSPEC_HIDDEN;
extern HRESULT TaskTriggerConstructor(LPVOID *ppObj) DECLSPEC_HIDDEN; extern HRESULT TaskSchedulerConstructor(LPVOID *ppObj) DECLSPEC_HIDDEN; -extern HRESULT TaskConstructor(ITaskFolder *folder, const WCHAR *task_name, ITask **task, BOOL create) DECLSPEC_HIDDEN; +extern HRESULT TaskConstructor(ITaskService *service, const WCHAR *task_name, ITask **task) DECLSPEC_HIDDEN; + +static inline WCHAR *heap_strdupW(const WCHAR *src) +{ + WCHAR *dst; + unsigned len; + if (!src) return NULL; + len = (strlenW(src) + 1) * sizeof(WCHAR); + if ((dst = heap_alloc(len))) memcpy(dst, src, len); + return dst; +}
#endif /* __MSTASK_PRIVATE_H__ */ diff --git a/dlls/mstask/task.c b/dlls/mstask/task.c index 095431cb04..e77a959e0f 100644 --- a/dlls/mstask/task.c +++ b/dlls/mstask/task.c @@ -36,7 +36,8 @@ typedef struct ITask ITask_iface; IPersistFile IPersistFile_iface; LONG ref; - IRegisteredTask *regtask; + ITaskDefinition *task; + LPWSTR task_name; LPWSTR applicationName; LPWSTR parameters; LPWSTR comment; @@ -57,6 +58,8 @@ static inline TaskImpl *impl_from_IPersistFile( IPersistFile *iface ) static void TaskDestructor(TaskImpl *This) { TRACE("%p\n", This); + ITaskDefinition_Release(This->task); + HeapFree(GetProcessHeap(), 0, This->task_name); HeapFree(GetProcessHeap(), 0, This->accountName); HeapFree(GetProcessHeap(), 0, This->comment); HeapFree(GetProcessHeap(), 0, This->parameters); @@ -762,49 +765,29 @@ static const IPersistFileVtbl MSTASK_IPersistFileVtbl = MSTASK_IPersistFile_GetCurFile };
-HRESULT TaskConstructor(ITaskFolder *folder, const WCHAR *task_name, ITask **task, BOOL create) +HRESULT TaskConstructor(ITaskService *service, const WCHAR *task_name, ITask **task) { TaskImpl *This; - IRegisteredTask *regtask; - BSTR bstr; + ITaskDefinition *taskdef; HRESULT hr;
TRACE("(%s, %p)\n", debugstr_w(task_name), task);
- bstr = SysAllocString(task_name); - if (!bstr) return E_OUTOFMEMORY; - - if (create) - { - static const char xml_tmplate[] = - "<?xml version=\"1.0\"?>\n" - "<Task xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task%5C%22%3E%5Cn" - "</Task>\n"; - WCHAR xmlW[sizeof(xml_tmplate)]; - VARIANT v_null; - - MultiByteToWideChar(CP_ACP, 0, xml_tmplate, -1, xmlW, sizeof(xmlW)/sizeof(xmlW[0])); - - V_VT(&v_null) = VT_NULL; - hr = ITaskFolder_RegisterTask(folder, bstr, xmlW, TASK_CREATE | TASK_UPDATE, - v_null, v_null, TASK_LOGON_NONE, v_null, ®task); - } - else - hr = ITaskFolder_GetTask(folder, bstr, ®task); - SysFreeString(bstr); + hr = ITaskService_NewTask(service, 0, &taskdef); if (hr != S_OK) return hr;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); if (!This) { - IRegisteredTask_Release(regtask); + ITaskDefinition_Release(taskdef); return E_OUTOFMEMORY; }
This->ITask_iface.lpVtbl = &MSTASK_ITaskVtbl; This->IPersistFile_iface.lpVtbl = &MSTASK_IPersistFileVtbl; This->ref = 1; - This->regtask = regtask; + This->task = taskdef; + This->task_name = heap_strdupW(task_name); This->applicationName = NULL; This->parameters = NULL; This->comment = NULL; diff --git a/dlls/mstask/task_scheduler.c b/dlls/mstask/task_scheduler.c index e9b8727633..6e17a57908 100644 --- a/dlls/mstask/task_scheduler.c +++ b/dlls/mstask/task_scheduler.c @@ -37,7 +37,6 @@ typedef struct ITaskScheduler ITaskScheduler_iface; LONG ref; ITaskService *service; - ITaskFolder *root; } TaskSchedulerImpl;
typedef struct @@ -59,7 +58,6 @@ static inline EnumWorkItemsImpl *impl_from_IEnumWorkItems(IEnumWorkItems *iface) static void TaskSchedulerDestructor(TaskSchedulerImpl *This) { TRACE("%p\n", This); - ITaskFolder_Release(This->root); ITaskService_Release(This->service); HeapFree(GetProcessHeap(), 0, This); InterlockedDecrement(&dll_ref); @@ -308,7 +306,7 @@ static HRESULT WINAPI MSTASK_ITaskScheduler_NewWorkItem( if (!IsEqualGUID(riid, &IID_ITask)) return E_NOINTERFACE;
- return TaskConstructor(This->root, task_name, (ITask **)task, TRUE); + return TaskConstructor(This->service, task_name, (ITask **)task); }
static HRESULT WINAPI MSTASK_ITaskScheduler_AddWorkItem( @@ -349,7 +347,6 @@ HRESULT TaskSchedulerConstructor(LPVOID *ppObj) { TaskSchedulerImpl *This; ITaskService *service; - ITaskFolder *root; VARIANT v_null; HRESULT hr;
@@ -366,24 +363,15 @@ HRESULT TaskSchedulerConstructor(LPVOID *ppObj) return hr; }
- hr = ITaskService_GetFolder(service, NULL, &root); - if (hr != S_OK) - { - ITaskService_Release(service); - return hr; - } - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); if (!This) { - ITaskFolder_Release(root); ITaskService_Release(service); return E_OUTOFMEMORY; }
This->ITaskScheduler_iface.lpVtbl = &MSTASK_ITaskSchedulerVtbl; This->service = service; - This->root = root; This->ref = 1;
*ppObj = &This->ITaskScheduler_iface;