taskschd: Implement task management using RPC APIs.
This commit is contained in:
parent
04c3680d11
commit
5c5d17e8f3
|
@ -202,7 +202,7 @@ static HRESULT WINAPI TaskFolder_CreateFolder(ITaskFolder *iface, BSTR path, VAR
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WCHAR *get_full_path(const WCHAR *parent, const WCHAR *path)
|
WCHAR *get_full_path(const WCHAR *parent, const WCHAR *path)
|
||||||
{
|
{
|
||||||
static const WCHAR bslash[] = { '\\', 0 };
|
static const WCHAR bslash[] = { '\\', 0 };
|
||||||
WCHAR *folder_path;
|
WCHAR *folder_path;
|
||||||
|
@ -262,12 +262,20 @@ static HRESULT WINAPI TaskFolder_DeleteFolder(ITaskFolder *iface, BSTR name, LON
|
||||||
static HRESULT WINAPI TaskFolder_GetTask(ITaskFolder *iface, BSTR name, IRegisteredTask **task)
|
static HRESULT WINAPI TaskFolder_GetTask(ITaskFolder *iface, BSTR name, IRegisteredTask **task)
|
||||||
{
|
{
|
||||||
TaskFolder *folder = impl_from_ITaskFolder(iface);
|
TaskFolder *folder = impl_from_ITaskFolder(iface);
|
||||||
|
ITaskDefinition *taskdef;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("%p,%s,%p\n", iface, debugstr_w(name), task);
|
TRACE("%p,%s,%p\n", iface, debugstr_w(name), task);
|
||||||
|
|
||||||
if (!task) return E_POINTER;
|
if (!task) return E_POINTER;
|
||||||
|
|
||||||
return RegisteredTask_create(folder->path, name, NULL, 0, task, FALSE);
|
hr = TaskDefinition_create(&taskdef);
|
||||||
|
if (hr != S_OK) return hr;
|
||||||
|
|
||||||
|
hr = RegisteredTask_create(folder->path, name, taskdef, 0, 0, task, FALSE);
|
||||||
|
if (hr != S_OK)
|
||||||
|
ITaskDefinition_Release(taskdef);
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI TaskFolder_GetTasks(ITaskFolder *iface, LONG flags, IRegisteredTaskCollection **tasks)
|
static HRESULT WINAPI TaskFolder_GetTasks(ITaskFolder *iface, LONG flags, IRegisteredTaskCollection **tasks)
|
||||||
|
@ -306,6 +314,8 @@ static HRESULT WINAPI TaskFolder_RegisterTask(ITaskFolder *iface, BSTR name, BST
|
||||||
VARIANT user, VARIANT password, TASK_LOGON_TYPE logon,
|
VARIANT user, VARIANT password, TASK_LOGON_TYPE logon,
|
||||||
VARIANT sddl, IRegisteredTask **task)
|
VARIANT sddl, IRegisteredTask **task)
|
||||||
{
|
{
|
||||||
|
TaskFolder *folder = impl_from_ITaskFolder(iface);
|
||||||
|
IRegisteredTask *regtask = NULL;
|
||||||
ITaskDefinition *taskdef;
|
ITaskDefinition *taskdef;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -314,14 +324,21 @@ static HRESULT WINAPI TaskFolder_RegisterTask(ITaskFolder *iface, BSTR name, BST
|
||||||
|
|
||||||
if (!xml) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER);
|
if (!xml) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER);
|
||||||
|
|
||||||
|
if (!task) task = ®task;
|
||||||
|
|
||||||
hr = TaskDefinition_create(&taskdef);
|
hr = TaskDefinition_create(&taskdef);
|
||||||
if (hr != S_OK) return hr;
|
if (hr != S_OK) return hr;
|
||||||
|
|
||||||
hr = ITaskDefinition_put_XmlText(taskdef, xml);
|
hr = ITaskDefinition_put_XmlText(taskdef, xml);
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
hr = ITaskFolder_RegisterTaskDefinition(iface, name, taskdef, flags, user, password, logon, sddl, task);
|
hr = RegisteredTask_create(folder->path, name, taskdef, flags, logon, task, TRUE);
|
||||||
|
|
||||||
|
if (hr != S_OK)
|
||||||
|
ITaskDefinition_Release(taskdef);
|
||||||
|
|
||||||
|
if (regtask)
|
||||||
|
IRegisteredTask_Release(regtask);
|
||||||
|
|
||||||
ITaskDefinition_Release(taskdef);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +361,10 @@ static HRESULT WINAPI TaskFolder_RegisterTaskDefinition(ITaskFolder *iface, BSTR
|
||||||
|
|
||||||
if (!task) task = ®task;
|
if (!task) task = ®task;
|
||||||
|
|
||||||
hr = RegisteredTask_create(folder->path, name, definition, logon, task, TRUE);
|
ITaskDefinition_AddRef(definition);
|
||||||
|
hr = RegisteredTask_create(folder->path, name, definition, flags, logon, task, TRUE);
|
||||||
|
if (hr != S_OK)
|
||||||
|
ITaskDefinition_Release(definition);
|
||||||
|
|
||||||
if (regtask)
|
if (regtask)
|
||||||
IRegisteredTask_Release(regtask);
|
IRegisteredTask_Release(regtask);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
#include "taskschd.h"
|
#include "taskschd.h"
|
||||||
|
#include "schrpc.h"
|
||||||
#include "taskschd_private.h"
|
#include "taskschd_private.h"
|
||||||
|
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
@ -266,18 +267,58 @@ static const IRegisteredTaskVtbl RegisteredTask_vtbl =
|
||||||
regtask_GetRunTimes
|
regtask_GetRunTimes
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT RegisteredTask_create(const WCHAR *path, const WCHAR *name, ITaskDefinition *definition,
|
HRESULT RegisteredTask_create(const WCHAR *path, const WCHAR *name, ITaskDefinition *definition, LONG flags,
|
||||||
TASK_LOGON_TYPE logon, IRegisteredTask **obj, BOOL create)
|
TASK_LOGON_TYPE logon, IRegisteredTask **obj, BOOL create)
|
||||||
{
|
{
|
||||||
|
WCHAR *full_name;
|
||||||
RegisteredTask *regtask;
|
RegisteredTask *regtask;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
full_name = get_full_path(path, name);
|
||||||
|
if (!full_name) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
regtask = heap_alloc(sizeof(*regtask));
|
regtask = heap_alloc(sizeof(*regtask));
|
||||||
if (!regtask) return E_OUTOFMEMORY;
|
if (!regtask)
|
||||||
|
{
|
||||||
|
heap_free(full_name);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
WCHAR *actual_path = NULL;
|
||||||
|
TASK_XML_ERROR_INFO *error_info = NULL;
|
||||||
|
BSTR xml = NULL;
|
||||||
|
|
||||||
|
hr = ITaskDefinition_get_XmlText(definition, &xml);
|
||||||
|
if (hr != S_OK || (hr = SchRpcRegisterTask(full_name, xml, flags, NULL, logon, 0, NULL, &actual_path, &error_info)) != S_OK)
|
||||||
|
{
|
||||||
|
heap_free(full_name);
|
||||||
|
heap_free(regtask);
|
||||||
|
SysFreeString(xml);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
MIDL_user_free(actual_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static const WCHAR languages[] = { 0 };
|
||||||
|
DWORD count = 0;
|
||||||
|
WCHAR *xml = NULL;
|
||||||
|
|
||||||
|
hr = SchRpcRetrieveTask(full_name, languages, &count, &xml);
|
||||||
|
if (hr != S_OK || (hr = ITaskDefinition_put_XmlText(definition, xml)) != S_OK)
|
||||||
|
{
|
||||||
|
heap_free(full_name);
|
||||||
|
heap_free(regtask);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
MIDL_user_free(xml);
|
||||||
|
}
|
||||||
|
|
||||||
regtask->IRegisteredTask_iface.lpVtbl = &RegisteredTask_vtbl;
|
regtask->IRegisteredTask_iface.lpVtbl = &RegisteredTask_vtbl;
|
||||||
regtask->path = heap_strdupW(path);
|
regtask->path = full_name;
|
||||||
regtask->ref = 1;
|
regtask->ref = 1;
|
||||||
ITaskDefinition_AddRef(definition);
|
|
||||||
regtask->taskdef = definition;
|
regtask->taskdef = definition;
|
||||||
*obj = ®task->IRegisteredTask_iface;
|
*obj = ®task->IRegisteredTask_iface;
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,11 @@ HRESULT TaskService_create(void **obj) DECLSPEC_HIDDEN;
|
||||||
HRESULT TaskDefinition_create(ITaskDefinition **obj) DECLSPEC_HIDDEN;
|
HRESULT TaskDefinition_create(ITaskDefinition **obj) DECLSPEC_HIDDEN;
|
||||||
HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj, BOOL create) DECLSPEC_HIDDEN;
|
HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj, BOOL create) DECLSPEC_HIDDEN;
|
||||||
HRESULT TaskFolderCollection_create(const WCHAR *path, ITaskFolderCollection **obj) DECLSPEC_HIDDEN;
|
HRESULT TaskFolderCollection_create(const WCHAR *path, ITaskFolderCollection **obj) DECLSPEC_HIDDEN;
|
||||||
HRESULT RegisteredTask_create(const WCHAR *path, const WCHAR *name, ITaskDefinition *definition, TASK_LOGON_TYPE logon,
|
HRESULT RegisteredTask_create(const WCHAR *path, const WCHAR *name, ITaskDefinition *definition, LONG flags,
|
||||||
IRegisteredTask **obj, BOOL create) DECLSPEC_HIDDEN;
|
TASK_LOGON_TYPE logon, IRegisteredTask **obj, BOOL create) DECLSPEC_HIDDEN;
|
||||||
HRESULT RegisteredTaskCollection_create(const WCHAR *path, IRegisteredTaskCollection **obj) DECLSPEC_HIDDEN;
|
HRESULT RegisteredTaskCollection_create(const WCHAR *path, IRegisteredTaskCollection **obj) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
WCHAR *get_full_path(const WCHAR *parent, const WCHAR *path) DECLSPEC_HIDDEN;
|
||||||
const char *debugstr_variant(const VARIANT *v) DECLSPEC_HIDDEN;
|
const char *debugstr_variant(const VARIANT *v) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static void *heap_alloc_zero(SIZE_T size) __WINE_ALLOC_SIZE(1);
|
static void *heap_alloc_zero(SIZE_T size) __WINE_ALLOC_SIZE(1);
|
||||||
|
|
|
@ -753,34 +753,25 @@ static void test_GetTask(void)
|
||||||
ITaskFolder_DeleteTask(root, Wine_Task2, 0);
|
ITaskFolder_DeleteTask(root, Wine_Task2, 0);
|
||||||
ITaskFolder_DeleteFolder(root, Wine, 0);
|
ITaskFolder_DeleteFolder(root, Wine, 0);
|
||||||
|
|
||||||
if (0) /* FIXME: Uncomment once implemented */
|
hr = ITaskFolder_GetTask(root, Wine_Task1, &task1);
|
||||||
{
|
ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr);
|
||||||
hr = ITaskFolder_GetTask(root, Wine_Task1, &task1);
|
|
||||||
ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr);
|
|
||||||
}
|
|
||||||
hr = ITaskFolder_CreateFolder(root, Wine, v_null, &folder);
|
hr = ITaskFolder_CreateFolder(root, Wine, v_null, &folder);
|
||||||
ok(hr == S_OK, "CreateFolder error %#x\n", hr);
|
ok(hr == S_OK, "CreateFolder error %#x\n", hr);
|
||||||
|
|
||||||
if (0) /* FIXME: Uncomment once implemented */
|
hr = ITaskFolder_GetTask(root, Wine, &task1);
|
||||||
{
|
todo_wine
|
||||||
hr = ITaskFolder_GetTask(root, Wine, &task1);
|
ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr);
|
||||||
ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, xml1, -1, xmlW, sizeof(xmlW)/sizeof(xmlW[0]));
|
MultiByteToWideChar(CP_ACP, 0, xml1, -1, xmlW, sizeof(xmlW)/sizeof(xmlW[0]));
|
||||||
|
|
||||||
for (i = 0; i < sizeof(create_new_task)/sizeof(create_new_task[0]); i++)
|
for (i = 0; i < sizeof(create_new_task)/sizeof(create_new_task[0]); i++)
|
||||||
{
|
{
|
||||||
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, create_new_task[i].flags, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, create_new_task[i].flags, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
||||||
/* FIXME: Remove once Wine is fixed */
|
|
||||||
if (create_new_task[i].hr != S_OK) todo_wine
|
|
||||||
ok(hr == create_new_task[i].hr, "%d: expected %#x, got %#x\n", i, create_new_task[i].hr, hr);
|
|
||||||
else
|
|
||||||
ok(hr == create_new_task[i].hr, "%d: expected %#x, got %#x\n", i, create_new_task[i].hr, hr);
|
ok(hr == create_new_task[i].hr, "%d: expected %#x, got %#x\n", i, create_new_task[i].hr, hr);
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
{
|
{
|
||||||
hr = ITaskFolder_DeleteTask(root, Wine_Task1, 0);
|
hr = ITaskFolder_DeleteTask(root, Wine_Task1, 0);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK, "DeleteTask error %#x\n", hr);
|
ok(hr == S_OK, "DeleteTask error %#x\n", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -799,11 +790,9 @@ todo_wine
|
||||||
ok(hr == S_OK, "RegisterTask error %#x\n", hr);
|
ok(hr == S_OK, "RegisterTask error %#x\n", hr);
|
||||||
|
|
||||||
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
||||||
todo_wine
|
|
||||||
ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
|
ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
|
||||||
|
|
||||||
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, 0, v_null, v_null, TASK_LOGON_NONE, v_null, NULL);
|
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, 0, v_null, v_null, TASK_LOGON_NONE, v_null, NULL);
|
||||||
todo_wine
|
|
||||||
ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
|
ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
|
||||||
|
|
||||||
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, TASK_CREATE_OR_UPDATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, TASK_CREATE_OR_UPDATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
||||||
|
@ -812,10 +801,6 @@ todo_wine
|
||||||
for (i = 0; i < sizeof(open_existing_task)/sizeof(open_existing_task[0]); i++)
|
for (i = 0; i < sizeof(open_existing_task)/sizeof(open_existing_task[0]); i++)
|
||||||
{
|
{
|
||||||
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, open_existing_task[i].flags, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, open_existing_task[i].flags, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
|
||||||
/* FIXME: Remove once Wine is fixed */
|
|
||||||
if (open_existing_task[i].hr != S_OK) todo_wine
|
|
||||||
ok(hr == open_existing_task[i].hr, "%d: expected %#x, got %#x\n", i, open_existing_task[i].hr, hr);
|
|
||||||
else
|
|
||||||
ok(hr == open_existing_task[i].hr, "%d: expected %#x, got %#x\n", i, open_existing_task[i].hr, hr);
|
ok(hr == open_existing_task[i].hr, "%d: expected %#x, got %#x\n", i, open_existing_task[i].hr, hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,7 +812,11 @@ todo_wine
|
||||||
todo_wine
|
todo_wine
|
||||||
ok(hr == S_OK, "get_Name error %#x\n", hr);
|
ok(hr == S_OK, "get_Name error %#x\n", hr);
|
||||||
/* FIXME: Remove once implemented */
|
/* FIXME: Remove once implemented */
|
||||||
if (hr != S_OK) goto failed;
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
ITaskFolder_DeleteTask(root, Wine_Task1, 0);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
ok(!lstrcmpW(bstr, Task1), "expected Task1, got %s\n", wine_dbgstr_w(bstr));
|
ok(!lstrcmpW(bstr, Task1), "expected Task1, got %s\n", wine_dbgstr_w(bstr));
|
||||||
SysFreeString(bstr);
|
SysFreeString(bstr);
|
||||||
hr = IRegisteredTask_get_Path(task1, &bstr);
|
hr = IRegisteredTask_get_Path(task1, &bstr);
|
||||||
|
|
Loading…
Reference in New Issue