Implements IRegisteredTaskCollection get_Item().
-- v3: taskschd/regtask: Implements IRegisteredTaskCollection get_Item(). taskschd/tests: Adds a test for IRegisteredTaskCollection get_Item().
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/taskschd/tests/scheduler.c | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+)
diff --git a/dlls/taskschd/tests/scheduler.c b/dlls/taskschd/tests/scheduler.c index f9c209f1d84..3166a615a31 100644 --- a/dlls/taskschd/tests/scheduler.c +++ b/dlls/taskschd/tests/scheduler.c @@ -1879,6 +1879,79 @@ static void test_TaskDefinition(void) ITaskService_Release(service); }
+static void test_get_item(void) +{ + HRESULT hr; + VARIANT v_null, index; + ITaskService *service; + ITaskFolder *folder, *root; + ITaskDefinition *task_def; + IRegistrationInfo *reg_info; + IActionCollection *actions; + IAction *action; + IExecAction *exec_action; + IRegisteredTask *task1, *ret_task1; + IRegisteredTaskCollection *tasks; + BSTR ret_task1_name = NULL; + + V_VT(&v_null) = VT_NULL; + + CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void**)&service); + ITaskService_Connect(service, v_null, v_null, v_null, v_null); + + hr = ITaskService_GetFolder(service, (BSTR)L"\", &root); + hr = ITaskFolder_CreateFolder(root,(BSTR)L"\Wine", v_null, &folder); + + hr = ITaskService_NewTask(service, 0, &task_def); + ITaskDefinition_get_RegistrationInfo(task_def, ®_info); + IRegistrationInfo_put_Author(reg_info, (BSTR)L"Wine Test"); + + ITaskDefinition_get_Actions(task_def, &actions); + IActionCollection_Create(actions, TASK_ACTION_EXEC, &action); + IAction_QueryInterface(action, &IID_IExecAction, (void**)&exec_action); + IExecAction_put_Path(exec_action, (BSTR)L"task1.exe"); + + ITaskFolder_RegisterTaskDefinition(folder, (BSTR)L"Task1", task_def, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1); + ITaskFolder_GetTasks(folder, TASK_ENUM_HIDDEN, &tasks); + + VariantInit(&index); + index.vt = VT_UI4; + index.uiVal = 1; + + hr = IRegisteredTaskCollection_get_Item(tasks, index, NULL); + ok(hr == E_POINTER, "expected E_POINTER, got %#lx\n", hr); + + index.uiVal = 0; + hr = IRegisteredTaskCollection_get_Item(tasks, index, &ret_task1); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); + + index.uiVal = 2; + hr = IRegisteredTaskCollection_get_Item(tasks, index, &ret_task1); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); + + index.uiVal = 1; + hr = IRegisteredTaskCollection_get_Item(tasks, index, &ret_task1); + ok(hr == S_OK, "expected S_OK, got %#lx\n", hr); + if (hr == S_OK) + { + IRegisteredTask_get_Name(ret_task1, &ret_task1_name); + if(ret_task1_name) + ok(!lstrcmpW(L"Task1", ret_task1_name), "expected name "Task1", got %ls\n", ret_task1_name); + else + ok(0, "expected name "Task1", got NULL\n"); + } + + ITaskFolder_DeleteTask(folder, (BSTR)L"Task1", 0); + ITaskFolder_DeleteFolder(root, (BSTR)L"\Wine", 0); + + SysFreeString(ret_task1_name); + IRegisteredTask_Release(task1); + IExecAction_Release(exec_action); + IRegistrationInfo_Release(reg_info); + ITaskDefinition_Release(task_def); + ITaskService_Release(service); +} + START_TEST(scheduler) { OleInitialize(NULL); @@ -1888,6 +1961,7 @@ START_TEST(scheduler) test_FolderCollection(); test_GetTask(); test_TaskDefinition(); + test_get_item();
OleUninitialize(); }
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/taskschd/regtask.c | 56 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-)
diff --git a/dlls/taskschd/regtask.c b/dlls/taskschd/regtask.c index bae0d4cb0b2..744f584b5a1 100644 --- a/dlls/taskschd/regtask.c +++ b/dlls/taskschd/regtask.c @@ -471,8 +471,60 @@ static HRESULT WINAPI regtasks_get_Count(IRegisteredTaskCollection *iface, LONG
static HRESULT WINAPI regtasks_get_Item(IRegisteredTaskCollection *iface, VARIANT index, IRegisteredTask **regtask) { - FIXME("%p,%s,%p: stub\n", iface, debugstr_variant(&index), regtask); - return E_NOTIMPL; + HRESULT hr; + WCHAR *xml = NULL; + VARIANT converted_index; + TASK_NAMES task_names = NULL; + ITaskDefinition *definition = NULL; + RegisteredTaskCollection *collection = NULL; + DWORD start_index = 0, num_tasks = 0; + + collection = impl_from_IRegisteredTaskCollection(iface); + if (!regtask) + return E_POINTER; + *regtask = NULL; + + VariantInit(&converted_index); + hr = VariantChangeType(&converted_index, &index, 0, VT_UI4); + if (FAILED(hr)) + return hr; + + start_index = V_UI4(&index); + if (start_index == 0) + { + VariantClear(&converted_index); + return E_INVALIDARG; + } + start_index -= 1; + + hr = SchRpcEnumTasks(collection->path, 0, &start_index, 1, &num_tasks, &task_names); + if (FAILED(hr)) + { + VariantClear(&converted_index); + return hr; + } + if (!task_names) + { + VariantClear(&converted_index); + return E_INVALIDARG; + } + + hr = TaskDefinition_create(&definition); + if (FAILED(hr)) + goto cleanup; + hr = RegisteredTask_create(collection->path, task_names[0], definition, TASK_VALIDATE_ONLY, TASK_LOGON_INTERACTIVE_TOKEN, regtask, FALSE); + if (FAILED(hr)) + goto cleanup; + + hr = S_OK; +cleanup: + MIDL_user_free(task_names[0]); + MIDL_user_free(task_names); + if (xml) + SysFreeString(xml); + VariantClear(&converted_index); + + return hr; }
static HRESULT WINAPI regtasks_get__NewEnum(IRegisteredTaskCollection *iface, IUnknown **penum)
You could probably merge the get_Item() and get_Count() tests.
On Tue May 27 15:35:54 2025 +0000, Alexandre Julliard wrote:
You could probably merge the get_Item() and get_Count() tests.
Do you mean in a single function to test for both get_item and get_Count or put both tests in one merge request?
On Tue May 27 15:35:54 2025 +0000, Jacob Czekalla wrote:
Do you mean in a single function to test for both get_item and get_Count or put both tests in one merge request?
A single function, it looks like there's a lot of duplication there.
On Tue May 27 15:39:52 2025 +0000, Alexandre Julliard wrote:
A single function, it looks like there's a lot of duplication there.
Okay, I will do that. Thank you.
This merge request was closed by Jacob Czekalla.