mf/session: Forward more events to the application.
[wine/zf.git] / dlls / taskschd / tests / scheduler.c
blobc03ecd35b97d8807e403138db3feda69f5bcb0ae
1 /*
2 * Copyright 2014 Dmitry Timoshkov
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.
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.
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
19 #include <stdarg.h>
20 #include <assert.h>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "initguid.h"
27 #include "objbase.h"
28 #include "taskschd.h"
30 #include <wine/test.h>
32 static void test_Connect(void)
34 static WCHAR empty[] = { 0 };
35 static const WCHAR deadbeefW[] = { '0','.','0','.','0','.','0',0 };
36 WCHAR comp_name[MAX_COMPUTERNAME_LENGTH + 1];
37 DWORD len;
38 HRESULT hr;
39 BSTR bstr;
40 VARIANT v_null, v_comp;
41 VARIANT_BOOL vbool;
42 BOOL was_connected;
43 ITaskService *service;
45 hr = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void **)&service);
46 if (hr != S_OK)
48 win_skip("CoCreateInstance(CLSID_TaskScheduler) error %#x\n", hr);
49 return;
52 hr = ITaskService_get_Connected(service, NULL);
53 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
55 vbool = 0xdead;
56 hr = ITaskService_get_Connected(service, &vbool);
57 ok(hr == S_OK, "get_Connected error %#x\n", hr);
58 ok(vbool == VARIANT_FALSE, "expected VARIANT_FALSE, got %d\n", vbool);
60 hr = ITaskService_get_TargetServer(service, NULL);
61 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
63 hr = ITaskService_get_TargetServer(service, &bstr);
64 ok(hr == HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED), "expected ERROR_ONLY_IF_CONNECTED, got %#x\n", hr);
66 /* Win7 doesn't support UNC \\ prefix, but according to a user
67 * comment on MSDN Win8 supports both ways.
69 len = ARRAY_SIZE(comp_name);
70 GetComputerNameW(comp_name, &len);
72 V_VT(&v_null) = VT_NULL;
74 V_VT(&v_comp) = VT_BSTR;
75 V_BSTR(&v_comp) = SysAllocString(comp_name);
77 hr = ITaskService_Connect(service, v_comp, v_null, v_null, v_null);
78 ok(hr == S_OK || hr == E_ACCESSDENIED /* not an administrator */, "Connect error %#x\n", hr);
79 was_connected = hr == S_OK;
80 SysFreeString(V_BSTR(&v_comp));
82 V_BSTR(&v_comp) = SysAllocString(deadbeefW);
83 hr = ITaskService_Connect(service, v_comp, v_null, v_null, v_null);
84 ok(hr == HRESULT_FROM_WIN32(RPC_S_INVALID_NET_ADDR) || hr == HRESULT_FROM_WIN32(ERROR_BAD_NETPATH) /* VM */,
85 "expected RPC_S_INVALID_NET_ADDR, got %#x\n", hr);
86 SysFreeString(V_BSTR(&v_comp));
88 vbool = 0xdead;
89 hr = ITaskService_get_Connected(service, &vbool);
90 ok(hr == S_OK, "get_Connected error %#x\n", hr);
91 ok(vbool == VARIANT_FALSE || (was_connected && vbool == VARIANT_TRUE),
92 "Connect shouldn't trash an existing connection, got %d (was connected %d)\n", vbool, was_connected);
94 V_BSTR(&v_comp) = SysAllocString(empty);
95 hr = ITaskService_Connect(service, v_comp, v_null, v_null, v_null);
96 ok(hr == S_OK, "Connect error %#x\n", hr);
97 SysFreeString(V_BSTR(&v_comp));
99 V_BSTR(&v_comp) = NULL;
100 hr = ITaskService_Connect(service, v_comp, v_null, v_null, v_null);
101 ok(hr == S_OK, "Connect error %#x\n", hr);
103 hr = ITaskService_Connect(service, v_null, v_null, v_null, v_null);
104 ok(hr == S_OK, "Connect error %#x\n", hr);
106 vbool = 0xdead;
107 hr = ITaskService_get_Connected(service, &vbool);
108 ok(hr == S_OK, "get_Connected error %#x\n", hr);
109 ok(vbool == VARIANT_TRUE, "expected VARIANT_TRUE, got %d\n", vbool);
111 hr = ITaskService_get_TargetServer(service, &bstr);
112 ok(hr == S_OK, "get_TargetServer error %#x\n", hr);
113 ok(!lstrcmpW(comp_name, bstr), "compname %s != server name %s\n", wine_dbgstr_w(comp_name), wine_dbgstr_w(bstr));
114 SysFreeString(bstr);
116 ITaskService_Release(service);
119 static void test_GetFolder(void)
121 static WCHAR dot[] = { '.',0 };
122 static WCHAR empty[] = { 0 };
123 static WCHAR slash[] = { '/',0 };
124 static WCHAR bslash[] = { '\\',0 };
125 static WCHAR Wine[] = { '\\','W','i','n','e',0 };
126 static WCHAR Wine_Folder1[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','1',0 };
127 static WCHAR Wine_Folder1_[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','1','\\',0 };
128 static WCHAR Wine_Folder1_Folder2[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','1','\\','F','o','l','d','e','r','2',0 };
129 static WCHAR Folder1_Folder2[] = { '\\','F','o','l','d','e','r','1','\\','F','o','l','d','e','r','2',0 };
130 static const WCHAR Folder1[] = { 'F','o','l','d','e','r','1',0 };
131 static const WCHAR Folder2[] = { 'F','o','l','d','e','r','2',0 };
132 HRESULT hr;
133 BSTR bstr;
134 VARIANT v_null;
135 ITaskService *service;
136 ITaskFolder *folder, *subfolder, *subfolder2;
138 hr = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void **)&service);
139 if (hr != S_OK)
141 win_skip("CoCreateInstance(CLSID_TaskScheduler) error %#x\n", hr);
142 return;
145 hr = ITaskService_GetFolder(service, NULL, &folder);
146 ok(hr == HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED), "expected ERROR_ONLY_IF_CONNECTED, got %#x\n", hr);
148 V_VT(&v_null) = VT_NULL;
150 hr = ITaskService_Connect(service, v_null, v_null, v_null, v_null);
151 ok(hr == S_OK, "Connect error %#x\n", hr);
153 hr = ITaskService_GetFolder(service, slash, &folder);
154 todo_wine
155 ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr);
157 hr = ITaskService_GetFolder(service, dot, &folder);
158 todo_wine
159 ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* win7 */,
160 "expected ERROR_INVALID_NAME, got %#x\n", hr);
162 hr = ITaskService_GetFolder(service, bslash, &folder);
163 ok(hr == S_OK, "GetFolder error %#x\n", hr);
164 ITaskFolder_Release(folder);
166 hr = ITaskService_GetFolder(service, NULL, NULL);
167 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
169 hr = ITaskService_GetFolder(service, empty, &folder);
170 ok(hr == S_OK, "GetFolder error %#x\n", hr);
171 ITaskFolder_Release(folder);
173 hr = ITaskService_GetFolder(service, NULL, &folder);
174 ok(hr == S_OK, "GetFolder error %#x\n", hr);
176 hr = ITaskFolder_get_Name(folder, NULL);
177 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
179 hr = ITaskFolder_get_Name(folder, &bstr);
180 ok (hr == S_OK, "get_Name error %#x\n", hr);
181 ok(!lstrcmpW(bstr, bslash), "expected '\\', got %s\n", wine_dbgstr_w(bstr));
182 SysFreeString(bstr);
184 hr = ITaskFolder_get_Path(folder, NULL);
185 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
187 hr = ITaskFolder_get_Path(folder, &bstr);
188 ok(hr == S_OK, "get_Path error %#x\n", hr);
189 ok(!lstrcmpW(bstr, bslash), "expected '\\', got %s\n", wine_dbgstr_w(bstr));
190 SysFreeString(bstr);
192 hr = ITaskFolder_CreateFolder(folder, NULL, v_null, &subfolder);
193 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
195 /* Just in case something was left from previous runs */
196 ITaskFolder_DeleteFolder(folder, Wine_Folder1_Folder2, 0);
197 ITaskFolder_DeleteFolder(folder, Wine_Folder1, 0);
198 ITaskFolder_DeleteFolder(folder, Wine, 0);
200 hr = ITaskFolder_CreateFolder(folder, slash, v_null, &subfolder);
201 todo_wine
202 ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr);
204 hr = ITaskService_GetFolder(service, Wine_Folder1_Folder2, &subfolder);
205 ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* win7 */,
206 "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr);
208 hr = ITaskFolder_CreateFolder(folder, bslash, v_null, &subfolder);
209 todo_wine
210 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
212 hr = ITaskFolder_CreateFolder(folder, Wine_Folder1_Folder2, v_null, &subfolder);
213 ok(hr == S_OK, "CreateFolder error %#x\n", hr);
214 ITaskFolder_Release(subfolder);
216 hr = ITaskFolder_CreateFolder(folder, Wine, v_null, NULL);
217 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
219 hr = ITaskFolder_CreateFolder(folder, Wine_Folder1_, v_null, &subfolder);
220 ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr);
222 hr = ITaskFolder_CreateFolder(folder, Wine, v_null, &subfolder);
223 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
224 hr = ITaskFolder_CreateFolder(folder, Wine+1, v_null, &subfolder);
225 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
226 hr = ITaskFolder_CreateFolder(folder, Wine_Folder1, v_null, &subfolder);
227 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
228 hr = ITaskFolder_CreateFolder(folder, Wine_Folder1+1, v_null, &subfolder);
229 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
230 hr = ITaskFolder_CreateFolder(folder, Wine_Folder1_Folder2, v_null, &subfolder);
231 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
232 hr = ITaskFolder_CreateFolder(folder, Wine_Folder1_Folder2+1, v_null, &subfolder);
233 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
235 hr = ITaskService_GetFolder(service, Wine_Folder1_Folder2, NULL);
236 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
238 hr = ITaskService_GetFolder(service, Wine_Folder1_Folder2, &subfolder);
239 ok(hr == S_OK, "GetFolder error %#x\n", hr);
241 hr = ITaskFolder_get_Name(subfolder, &bstr);
242 ok (hr == S_OK, "get_Name error %#x\n", hr);
243 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
244 SysFreeString(bstr);
245 hr = ITaskFolder_get_Path(subfolder, &bstr);
246 ok(hr == S_OK, "get_Path error %#x\n", hr);
247 ok(!lstrcmpW(bstr, Wine_Folder1_Folder2), "expected \\Wine\\Folder1\\Folder2, got %s\n", wine_dbgstr_w(bstr));
248 SysFreeString(bstr);
249 ITaskFolder_Release(subfolder);
251 hr = ITaskService_GetFolder(service, Wine_Folder1_Folder2+1, &subfolder);
252 ok(hr == S_OK, "GetFolder error %#x\n", hr);
253 hr = ITaskFolder_get_Name(subfolder, &bstr);
254 ok (hr == S_OK, "get_Name error %#x\n", hr);
255 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
256 SysFreeString(bstr);
257 hr = ITaskFolder_get_Path(subfolder, &bstr);
258 ok(hr == S_OK, "get_Path error %#x\n", hr);
259 ok(!lstrcmpW(bstr, Wine_Folder1_Folder2+1), "expected Wine\\Folder1\\Folder2, got %s\n", wine_dbgstr_w(bstr));
260 SysFreeString(bstr);
261 ITaskFolder_Release(subfolder);
263 hr = ITaskService_GetFolder(service, Wine_Folder1, &subfolder);
264 ok(hr == S_OK, "GetFolder error %#x\n", hr);
265 hr = ITaskFolder_get_Name(subfolder, &bstr);
266 ok (hr == S_OK, "get_Name error %#x\n", hr);
267 ok(!lstrcmpW(bstr, Folder1), "expected Folder1, got %s\n", wine_dbgstr_w(bstr));
268 SysFreeString(bstr);
269 hr = ITaskFolder_get_Path(subfolder, &bstr);
270 ok(hr == S_OK, "get_Path error %#x\n", hr);
271 ok(!lstrcmpW(bstr, Wine_Folder1), "expected \\Wine\\Folder1, got %s\n", wine_dbgstr_w(bstr));
272 SysFreeString(bstr);
273 ITaskFolder_Release(subfolder);
275 hr = ITaskService_GetFolder(service, Wine, &subfolder);
276 ok(hr == S_OK, "GetFolder error %#x\n", hr);
277 hr = ITaskFolder_get_Name(subfolder, &bstr);
278 ok (hr == S_OK, "get_Name error %#x\n", hr);
279 ok(!lstrcmpW(bstr, Wine+1), "expected Wine, got %s\n", wine_dbgstr_w(bstr));
280 SysFreeString(bstr);
281 hr = ITaskFolder_get_Path(subfolder, &bstr);
282 ok(hr == S_OK, "get_Path error %#x\n", hr);
283 ok(!lstrcmpW(bstr, Wine), "expected \\Wine, got %s\n", wine_dbgstr_w(bstr));
284 SysFreeString(bstr);
285 ITaskFolder_Release(subfolder);
287 hr = ITaskService_GetFolder(service, Wine+1, &subfolder);
288 ok(hr == S_OK, "GetFolder error %#x\n", hr);
289 hr = ITaskFolder_get_Name(subfolder, &bstr);
290 ok (hr == S_OK, "get_Name error %#x\n", hr);
291 ok(!lstrcmpW(bstr, Wine+1), "expected Wine, got %s\n", wine_dbgstr_w(bstr));
292 SysFreeString(bstr);
293 hr = ITaskFolder_get_Path(subfolder, &bstr);
294 ok(hr == S_OK, "get_Path error %#x\n", hr);
295 ok(!lstrcmpW(bstr, Wine+1), "expected Wine, got %s\n", wine_dbgstr_w(bstr));
296 SysFreeString(bstr);
298 hr = ITaskFolder_GetFolder(subfolder, bslash, &subfolder2);
299 ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr);
301 hr = ITaskFolder_GetFolder(subfolder, NULL, &subfolder2);
302 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
304 hr = ITaskFolder_GetFolder(subfolder, empty, &subfolder2);
305 ok(hr == S_OK, "GetFolder error %#x\n", hr);
306 hr = ITaskFolder_get_Name(subfolder2, &bstr);
307 ok (hr == S_OK, "get_Name error %#x\n", hr);
308 ok(!lstrcmpW(bstr, Wine+1), "expected Wine, got %s\n", wine_dbgstr_w(bstr));
309 SysFreeString(bstr);
310 hr = ITaskFolder_get_Path(subfolder2, &bstr);
311 ok(hr == S_OK, "get_Path error %#x\n", hr);
312 ok(!lstrcmpW(bstr, Wine+1), "expected Wine, got %s\n", wine_dbgstr_w(bstr));
313 SysFreeString(bstr);
314 ITaskFolder_Release(subfolder2);
316 hr = ITaskFolder_GetFolder(subfolder, Folder1_Folder2, &subfolder2);
317 ok(hr == S_OK, "GetFolder error %#x\n", hr);
318 hr = ITaskFolder_get_Name(subfolder2, &bstr);
319 ok (hr == S_OK, "get_Name error %#x\n", hr);
320 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
321 SysFreeString(bstr);
322 hr = ITaskFolder_get_Path(subfolder2, &bstr);
323 ok(hr == S_OK, "get_Path error %#x\n", hr);
324 ok(!lstrcmpW(bstr, Wine_Folder1_Folder2+1), "expected Wine\\Folder1\\Folder2, got %s\n", wine_dbgstr_w(bstr));
325 SysFreeString(bstr);
326 ITaskFolder_Release(subfolder2);
328 hr = ITaskFolder_GetFolder(subfolder, Folder1_Folder2+1, &subfolder2);
329 ok(hr == S_OK, "GetFolder error %#x\n", hr);
331 hr = ITaskFolder_get_Name(subfolder2, &bstr);
332 ok (hr == S_OK, "get_Name error %#x\n", hr);
333 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
334 SysFreeString(bstr);
335 hr = ITaskFolder_get_Path(subfolder2, &bstr);
336 ok(hr == S_OK, "get_Path error %#x\n", hr);
337 ok(!lstrcmpW(bstr, Wine_Folder1_Folder2+1), "expected Wine\\Folder1\\Folder2, got %s\n", wine_dbgstr_w(bstr));
338 SysFreeString(bstr);
339 ITaskFolder_Release(subfolder2);
341 ITaskFolder_Release(subfolder);
343 hr = ITaskFolder_DeleteFolder(folder, Wine, 0);
344 ok(hr == HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY), "expected ERROR_DIR_NOT_EMPTY, got %#x\n", hr);
346 hr = ITaskFolder_DeleteFolder(folder, Wine_Folder1_Folder2, 0);
347 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
348 hr = ITaskFolder_DeleteFolder(folder, Wine_Folder1+1, 0);
349 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
350 hr = ITaskFolder_DeleteFolder(folder, Wine+1, 0);
351 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
353 hr = ITaskFolder_DeleteFolder(folder, Wine, 0);
354 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || hr == S_OK /* win7 */, "expected ERROR_FILE_NOT_FOUND, got %#x\n", hr);
356 hr = ITaskFolder_DeleteFolder(folder, NULL, 0);
357 ok(hr == E_ACCESSDENIED || hr == E_INVALIDARG /* Vista */, "expected E_ACCESSDENIED, got %#x\n", hr);
359 hr = ITaskFolder_DeleteFolder(folder, empty, 0);
360 ok(hr == E_ACCESSDENIED || hr == E_INVALIDARG /* Vista */, "expected E_ACCESSDENIED, got %#x\n", hr);
362 hr = ITaskFolder_DeleteFolder(folder, slash, 0);
363 todo_wine
364 ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr);
366 ITaskFolder_Release(folder);
367 ITaskService_Release(service);
370 static void set_var(int vt, VARIANT *var, LONG val)
372 V_VT(var) = vt;
374 switch(vt)
376 case VT_I1:
377 case VT_UI1:
378 V_UI1(var) = (BYTE)val;
379 break;
381 case VT_I2:
382 case VT_UI2:
383 V_UI2(var) = (USHORT)val;
384 break;
386 case VT_I4:
387 case VT_UI4:
388 V_UI4(var) = val;
389 break;
391 case VT_I8:
392 case VT_UI8:
393 V_UI8(var) = val;
394 break;
396 case VT_INT:
397 case VT_UINT:
398 V_UINT(var) = val;
399 break;
401 default:
402 assert(0);
403 break;
407 static void test_FolderCollection(void)
409 static WCHAR Wine[] = { '\\','W','i','n','e',0 };
410 static WCHAR Wine_Folder1[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','1',0 };
411 static WCHAR Wine_Folder2[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','2',0 };
412 static WCHAR Wine_Folder3[] = { '\\','W','i','n','e','\\','F','o','l','d','e','r','3',0 };
413 static const WCHAR Folder1[] = { 'F','o','l','d','e','r','1',0 };
414 static const WCHAR Folder2[] = { 'F','o','l','d','e','r','2',0 };
415 HRESULT hr;
416 BSTR bstr;
417 VARIANT v_null, var[3];
418 ITaskService *service;
419 ITaskFolder *root, *folder, *subfolder;
420 ITaskFolderCollection *folders;
421 IUnknown *unknown;
422 IEnumVARIANT *enumvar;
423 ULONG count, i;
424 BOOL is_first;
425 VARIANT idx;
426 static const int vt[] = { VT_I1, VT_I2, VT_I4, VT_I8, VT_UI1, VT_UI2, VT_UI4, VT_UI8, VT_INT, VT_UINT };
428 hr = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void **)&service);
429 if (hr != S_OK)
431 win_skip("CoCreateInstance(CLSID_TaskScheduler) error %#x\n", hr);
432 return;
435 V_VT(&v_null) = VT_NULL;
437 hr = ITaskService_Connect(service, v_null, v_null, v_null, v_null);
438 ok(hr == S_OK, "Connect error %#x\n", hr);
440 hr = ITaskService_GetFolder(service, NULL, &root);
441 ok(hr == S_OK, "GetFolder error %#x\n", hr);
443 /* Just in case something was left from previous runs */
444 ITaskFolder_DeleteFolder(root, Wine_Folder1, 0);
445 ITaskFolder_DeleteFolder(root, Wine_Folder2, 0);
446 ITaskFolder_DeleteFolder(root, Wine_Folder3, 0);
447 ITaskFolder_DeleteFolder(root, Wine, 0);
449 hr = ITaskFolder_CreateFolder(root, Wine_Folder1, v_null, &subfolder);
450 ok(hr == S_OK, "CreateFolder error %#x\n", hr);
451 ITaskFolder_Release(subfolder);
453 hr = ITaskFolder_CreateFolder(root, Wine_Folder2, v_null, &subfolder);
454 ok(hr == S_OK, "CreateFolder error %#x\n", hr);
455 ITaskFolder_Release(subfolder);
457 hr = ITaskFolder_GetFolder(root, Wine, &folder);
458 ok(hr == S_OK, "GetFolder error %#x\n", hr);
460 hr = ITaskFolder_GetFolders(folder, 0, NULL);
461 ok (hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
463 hr = ITaskFolder_GetFolders(folder, 0, &folders);
464 ok(hr == S_OK, "GetFolders error %#x\n", hr);
466 ITaskFolder_Release(folder);
468 hr = ITaskFolderCollection_get_Count(folders, NULL);
469 ok (hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
471 count = 0;
472 hr = ITaskFolderCollection_get_Count(folders, (LONG *)&count);
473 ok(hr == S_OK, "get_Count error %#x\n", hr);
474 ok(count == 2, "expected 2, got %d\n", count);
476 hr = ITaskFolder_CreateFolder(root, Wine_Folder3, v_null, &subfolder);
477 ok(hr == S_OK, "CreateFolder error %#x\n", hr);
478 ITaskFolder_Release(subfolder);
480 count = 0;
481 hr = ITaskFolderCollection_get_Count(folders, (LONG *)&count);
482 ok(hr == S_OK, "get_Count error %#x\n", hr);
483 ok(count == 2, "expected 2, got %d\n", count);
485 set_var(VT_INT, &idx, 0);
486 hr = ITaskFolderCollection_get_Item(folders, idx, NULL);
487 ok (hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
489 for (i = 0; i < ARRAY_SIZE(vt); i++)
491 set_var(vt[i], &idx, 1);
492 hr = ITaskFolderCollection_get_Item(folders, idx, &subfolder);
493 ok(hr == S_OK, "get_Item(vt = %d) error %#x\n", vt[i], hr);
494 ITaskFolder_Release(subfolder);
497 for (i = 0; i <= count; i++)
499 V_VT(&idx) = VT_I4;
500 V_UI4(&idx) = i;
501 hr = ITaskFolderCollection_get_Item(folders, idx, &subfolder);
502 if (i == 0)
504 ok (hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
505 continue;
507 ok(hr == S_OK, "get_Item error %#x\n", hr);
509 hr = ITaskFolder_get_Path(subfolder, &bstr);
510 ok(hr == S_OK, "get_Path error %#x\n", hr);
511 is_first = !lstrcmpW(bstr, Wine_Folder1);
512 if (is_first)
513 ok(!lstrcmpW(bstr, Wine_Folder1), "expected \\Wine\\Folder1, got %s\n", wine_dbgstr_w(bstr));
514 else
515 ok(!lstrcmpW(bstr, Wine_Folder2), "expected \\Wine\\Folder2, got %s\n", wine_dbgstr_w(bstr));
516 SysFreeString(bstr);
518 hr = ITaskFolder_get_Name(subfolder, &bstr);
519 ok(hr == S_OK, "get_Name error %#x\n", hr);
520 if (is_first)
521 ok(!lstrcmpW(bstr, Folder1), "expected Folder1, got %s\n", wine_dbgstr_w(bstr));
522 else
523 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
525 ITaskFolder_Release(subfolder);
527 V_VT(&idx) = VT_BSTR;
528 V_BSTR(&idx) = bstr;
529 hr = ITaskFolderCollection_get_Item(folders, idx, &subfolder);
530 ok(hr == S_OK, "get_Item error %#x\n", hr);
531 SysFreeString(bstr);
533 hr = ITaskFolder_get_Path(subfolder, &bstr);
534 ok(hr == S_OK, "get_Path error %#x\n", hr);
535 if (is_first)
536 ok(!lstrcmpW(bstr, Wine_Folder1), "expected \\Wine\\Folder1, got %s\n", wine_dbgstr_w(bstr));
537 else
538 ok(!lstrcmpW(bstr, Wine_Folder2), "expected \\Wine\\Folder2, got %s\n", wine_dbgstr_w(bstr));
539 SysFreeString(bstr);
541 hr = ITaskFolder_get_Name(subfolder, &bstr);
542 ok(hr == S_OK, "get_Name error %#x\n", hr);
543 if (is_first)
544 ok(!lstrcmpW(bstr, Folder1), "expected Folder1, got %s\n", wine_dbgstr_w(bstr));
545 else
546 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
547 SysFreeString(bstr);
549 ITaskFolder_Release(subfolder);
552 V_VT(&idx) = VT_I4;
553 V_UI4(&idx) = 3;
554 hr = ITaskFolderCollection_get_Item(folders, idx, &subfolder);
555 ok (hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
557 hr = ITaskFolderCollection_QueryInterface(folders, &IID_IEnumVARIANT, (void **)&enumvar);
558 ok(hr == E_NOINTERFACE, "expected E_NOINTERFACE, got %#x\n", hr);
559 hr = ITaskFolderCollection_QueryInterface(folders, &IID_IEnumUnknown, (void **)&enumvar);
560 ok(hr == E_NOINTERFACE, "expected E_NOINTERFACE, got %#x\n", hr);
562 hr = ITaskFolderCollection_get__NewEnum(folders, NULL);
563 ok (hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
565 hr = ITaskFolderCollection_get__NewEnum(folders, &unknown);
566 ok(hr == S_OK, "get__NewEnum error %#x\n", hr);
567 hr = IUnknown_QueryInterface(unknown, &IID_IEnumUnknown, (void **)&enumvar);
568 ok(hr == E_NOINTERFACE, "expected E_NOINTERFACE, got %#x\n", hr);
569 hr = IUnknown_QueryInterface(unknown, &IID_IEnumVARIANT, (void **)&enumvar);
570 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
571 IEnumVARIANT_Release(enumvar);
573 hr = IUnknown_QueryInterface(unknown, &IID_IUnknown, (void **)&enumvar);
574 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
575 IUnknown_Release(unknown);
577 hr = IEnumVARIANT_Skip(enumvar, 0);
578 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
579 hr = IEnumVARIANT_Skip(enumvar, 2);
580 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
581 hr = IEnumVARIANT_Skip(enumvar, 1);
582 ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr);
584 hr = IEnumVARIANT_Reset(enumvar);
585 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
587 count = -1;
588 hr = IEnumVARIANT_Next(enumvar, 1, NULL, &count);
589 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
591 memset(var, 0, sizeof(var));
592 count = -1;
593 hr = IEnumVARIANT_Next(enumvar, 1, var, &count);
594 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
595 ok(count == 1, "expected 1, got %d\n", count);
596 hr = ITaskFolder_get_Path((ITaskFolder *)V_DISPATCH(&var[0]), &bstr);
597 ok(hr == S_OK, "get_Path error %#x\n", hr);
598 is_first = !lstrcmpW(bstr, Wine_Folder1);
599 if (is_first)
600 ok(!lstrcmpW(bstr, Wine_Folder1), "expected \\Wine\\Folder1, got %s\n", wine_dbgstr_w(bstr));
601 else
602 ok(!lstrcmpW(bstr, Wine_Folder2), "expected \\Wine\\Folder2, got %s\n", wine_dbgstr_w(bstr));
603 SysFreeString(bstr);
604 hr = ITaskFolder_get_Name((ITaskFolder *)V_DISPATCH(&var[0]), &bstr);
605 ok(hr == S_OK, "get_Name error %#x\n", hr);
606 if (is_first)
607 ok(!lstrcmpW(bstr, Folder1), "expected Folder1, got %s\n", wine_dbgstr_w(bstr));
608 else
609 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
610 SysFreeString(bstr);
611 IDispatch_Release(V_DISPATCH(&var[0]));
613 memset(var, 0, sizeof(var));
614 count = -1;
615 hr = IEnumVARIANT_Next(enumvar, 1, var, &count);
616 ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr);
617 ok(count == 0, "expected 0, got %d\n", count);
619 count = -1;
620 hr = IEnumVARIANT_Next(enumvar, 1, NULL, &count);
621 ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr);
622 ok(count == 0, "expected 0, got %d\n", count);
624 hr = IEnumVARIANT_Reset(enumvar);
625 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
627 memset(var, 0, sizeof(var));
628 count = -1;
629 hr = IEnumVARIANT_Next(enumvar, 3, var, &count);
630 ok(hr == S_FALSE, "expected S_FALSE, got %#x\n", hr);
631 ok(count == 2, "expected 2, got %d\n", count);
632 ok(V_VT(&var[0]) == VT_DISPATCH, "expected VT_DISPATCH, got %d\n", V_VT(&var[0]));
633 ok(V_VT(&var[1]) == VT_DISPATCH, "expected VT_DISPATCH, got %d\n", V_VT(&var[1]));
634 IEnumVARIANT_Release(enumvar);
636 for (i = 0; i < count; i++)
638 hr = IDispatch_QueryInterface(V_DISPATCH(&var[i]), &IID_ITaskFolder, (void **)&subfolder);
639 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
641 hr = ITaskFolder_get_Path(subfolder, &bstr);
642 ok(hr == S_OK, "get_Path error %#x\n", hr);
643 is_first = !lstrcmpW(bstr, Wine_Folder1);
644 if (is_first)
645 ok(!lstrcmpW(bstr, Wine_Folder1), "expected \\Wine\\Folder1, got %s\n", wine_dbgstr_w(bstr));
646 else
647 ok(!lstrcmpW(bstr, Wine_Folder2), "expected \\Wine\\Folder2, got %s\n", wine_dbgstr_w(bstr));
648 SysFreeString(bstr);
650 hr = ITaskFolder_get_Name(subfolder, &bstr);
651 ok(hr == S_OK, "get_Name error %#x\n", hr);
652 if (is_first)
653 ok(!lstrcmpW(bstr, Folder1), "expected Folder1, got %s\n", wine_dbgstr_w(bstr));
654 else
655 ok(!lstrcmpW(bstr, Folder2), "expected Folder2, got %s\n", wine_dbgstr_w(bstr));
656 SysFreeString(bstr);
658 ITaskFolder_Release(subfolder);
661 IDispatch_Release(V_DISPATCH(&var[0]));
662 IDispatch_Release(V_DISPATCH(&var[1]));
664 ITaskFolderCollection_Release(folders);
666 hr = ITaskFolder_DeleteFolder(root, Wine_Folder1, 0);
667 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
668 hr = ITaskFolder_DeleteFolder(root, Wine_Folder2, 0);
669 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
670 hr = ITaskFolder_DeleteFolder(root, Wine_Folder3, 0);
671 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
672 hr = ITaskFolder_DeleteFolder(root, Wine, 0);
673 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
675 ITaskFolder_Release(root);
676 ITaskService_Release(service);
679 static void test_GetTask(void)
681 static WCHAR Wine[] = { '\\','W','i','n','e',0 };
682 static WCHAR Wine_Task1[] = { '\\','W','i','n','e','\\','T','a','s','k','1',0 };
683 static WCHAR Wine_Task2[] = { '\\','W','i','n','e','\\','T','a','s','k','2',0 };
684 static WCHAR Task1[] = { 'T','a','s','k','1',0 };
685 static WCHAR Task2[] = { 'T','a','s','k','2',0 };
686 static const char xml1[] =
687 "<?xml version=\"1.0\"?>\n"
688 "<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n"
689 " <RegistrationInfo>\n"
690 " <Description>\"Task1\"</Description>\n"
691 " </RegistrationInfo>\n"
692 " <Settings>\n"
693 " <Enabled>false</Enabled>\n"
694 " <Hidden>false</Hidden>\n"
695 " </Settings>\n"
696 " <Actions>\n"
697 " <Exec>\n"
698 " <Command>\"task1.exe\"</Command>\n"
699 " </Exec>\n"
700 " </Actions>\n"
701 "</Task>\n";
702 static const char xml2[] =
703 "<?xml version=\"1.0\"?>\n"
704 "<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n"
705 " <RegistrationInfo>\n"
706 " <Description>\"Task2\"</Description>\n"
707 " </RegistrationInfo>\n"
708 " <Settings>\n"
709 " <Enabled>true</Enabled>\n"
710 " <Hidden>true</Hidden>\n"
711 " </Settings>\n"
712 " <Actions>\n"
713 " <Exec>\n"
714 " <Command>\"task2.exe\"</Command>\n"
715 " </Exec>\n"
716 " </Actions>\n"
717 "</Task>\n";
718 static const struct
720 DWORD flags, hr;
721 } create_new_task[] =
723 { 0, S_OK },
724 { TASK_CREATE, S_OK },
725 { TASK_UPDATE, 0x80070002 /* HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) */ },
726 { TASK_CREATE | TASK_UPDATE, S_OK }
728 static const struct
730 DWORD flags, hr;
731 } open_existing_task[] =
733 { 0, 0x800700b7 /* HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) */ },
734 { TASK_CREATE, 0x800700b7 /* HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) */ },
735 { TASK_UPDATE, S_OK },
736 { TASK_CREATE | TASK_UPDATE, S_OK }
738 WCHAR xmlW[sizeof(xml1)];
739 HRESULT hr;
740 BSTR bstr;
741 TASK_STATE state;
742 VARIANT_BOOL vbool;
743 VARIANT v_null;
744 ITaskService *service;
745 ITaskFolder *root, *folder;
746 IRegisteredTask *task1, *task2;
747 IID iid;
748 int i;
750 hr = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void **)&service);
751 if (hr != S_OK)
753 win_skip("CoCreateInstance(CLSID_TaskScheduler) error %#x\n", hr);
754 return;
757 V_VT(&v_null) = VT_NULL;
759 hr = ITaskService_Connect(service, v_null, v_null, v_null, v_null);
760 ok(hr == S_OK, "Connect error %#x\n", hr);
762 hr = ITaskService_GetFolder(service, NULL, &root);
763 ok(hr == S_OK, "GetFolder error %#x\n", hr);
765 /* Just in case something was left from previous runs */
766 ITaskFolder_DeleteTask(root, Wine_Task1, 0);
767 ITaskFolder_DeleteTask(root, Wine_Task2, 0);
768 ITaskFolder_DeleteFolder(root, Wine, 0);
770 hr = ITaskFolder_GetTask(root, Wine_Task1, &task1);
771 ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* win7 */,
772 "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr);
774 hr = ITaskFolder_CreateFolder(root, Wine, v_null, &folder);
775 ok(hr == S_OK, "CreateFolder error %#x\n", hr);
777 hr = ITaskFolder_GetTask(root, Wine, &task1);
778 ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* win7 */,
779 "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr);
781 MultiByteToWideChar(CP_ACP, 0, xml1, -1, xmlW, ARRAY_SIZE(xmlW));
783 for (i = 0; i < ARRAY_SIZE(create_new_task); i++)
785 hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, create_new_task[i].flags, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
786 ok(hr == create_new_task[i].hr, "%d: expected %#x, got %#x\n", i, create_new_task[i].hr, hr);
787 if (hr == S_OK)
789 hr = ITaskFolder_DeleteTask(root, Wine_Task1, 0);
790 ok(hr == S_OK, "DeleteTask error %#x\n", hr);
791 IRegisteredTask_Release(task1);
795 hr = ITaskFolder_RegisterTask(root, Wine_Task1, NULL, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, NULL);
796 ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "expected RPC_X_NULL_REF_POINTER, got %#x\n", hr);
798 hr = ITaskFolder_RegisterTask(root, Wine, xmlW, TASK_VALIDATE_ONLY, v_null, v_null, TASK_LOGON_NONE, v_null, NULL);
799 ok(hr == S_OK, "RegisterTask error %#x\n", hr);
801 hr = ITaskFolder_RegisterTask(root, Wine, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, NULL);
802 todo_wine
803 ok(hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) || broken(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) /* Vista */, "expected ERROR_ACCESS_DENIED, got %#x\n", hr);
805 hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, NULL);
806 ok(hr == S_OK, "RegisterTask error %#x\n", hr);
808 hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
809 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
811 hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, 0, v_null, v_null, TASK_LOGON_NONE, v_null, NULL);
812 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
814 hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, TASK_CREATE_OR_UPDATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
815 ok(hr == S_OK, "RegisterTask error %#x\n", hr);
817 for (i = 0; i < ARRAY_SIZE(open_existing_task); i++)
819 hr = ITaskFolder_RegisterTask(root, Wine_Task1, xmlW, open_existing_task[i].flags, v_null, v_null, TASK_LOGON_NONE, v_null, &task2);
820 ok(hr == open_existing_task[i].hr, "%d: expected %#x, got %#x\n", i, open_existing_task[i].hr, hr);
821 if (hr == S_OK)
822 IRegisteredTask_Release(task2);
825 hr = IRegisteredTask_get_Name(task1, NULL);
826 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
828 hr = IRegisteredTask_get_Name(task1, &bstr);
829 ok(hr == S_OK, "get_Name error %#x\n", hr);
830 ok(!lstrcmpW(bstr, Task1), "expected Task1, got %s\n", wine_dbgstr_w(bstr));
831 SysFreeString(bstr);
832 hr = IRegisteredTask_get_Path(task1, &bstr);
833 ok(hr == S_OK, "get_Path error %#x\n", hr);
834 ok(!lstrcmpW(bstr, Wine_Task1), "expected \\Wine\\Task1, got %s\n", wine_dbgstr_w(bstr));
835 SysFreeString(bstr);
836 hr = IRegisteredTask_get_State(task1, &state);
837 ok(hr == S_OK, "get_State error %#x\n", hr);
838 ok(state == TASK_STATE_DISABLED, "expected TASK_STATE_DISABLED, got %d\n", state);
839 hr = IRegisteredTask_get_Enabled(task1, &vbool);
840 ok(hr == S_OK, "get_Enabled error %#x\n", hr);
841 ok(vbool == VARIANT_FALSE, "expected VARIANT_FALSE, got %d\n", vbool);
843 IRegisteredTask_Release(task1);
845 hr = ITaskFolder_RegisterTask(folder, Task1, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task2);
846 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);
848 MultiByteToWideChar(CP_ACP, 0, xml2, -1, xmlW, ARRAY_SIZE(xmlW));
850 hr = ITaskFolder_RegisterTask(folder, Task2, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task2);
851 ok(hr == S_OK, "RegisterTask error %#x\n", hr);
853 hr = IRegisteredTask_get_Name(task2, &bstr);
854 ok(hr == S_OK, "get_Name error %#x\n", hr);
855 ok(!lstrcmpW(bstr, Task2), "expected Task2, got %s\n", wine_dbgstr_w(bstr));
856 SysFreeString(bstr);
857 hr = IRegisteredTask_get_Path(task2, &bstr);
858 ok(hr == S_OK, "get_Path error %#x\n", hr);
859 ok(!lstrcmpW(bstr, Wine_Task2), "expected \\Wine\\Task2, got %s\n", wine_dbgstr_w(bstr));
860 SysFreeString(bstr);
861 hr = IRegisteredTask_get_State(task2, &state);
862 ok(hr == S_OK, "get_State error %#x\n", hr);
863 todo_wine
864 ok(state == TASK_STATE_READY, "expected TASK_STATE_READY, got %d\n", state);
865 hr = IRegisteredTask_get_Enabled(task2, &vbool);
866 ok(hr == S_OK, "get_Enabled error %#x\n", hr);
867 todo_wine
868 ok(vbool == VARIANT_TRUE, "expected VARIANT_TRUE, got %d\n", vbool);
870 IRegisteredTask_Release(task2);
872 hr = ITaskFolder_GetTask(root, NULL, &task1);
873 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
875 hr = ITaskFolder_GetTask(root, Wine_Task1, NULL);
876 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
878 hr = ITaskFolder_GetTask(root, Wine_Task1, &task1);
879 ok(hr == S_OK, "GetTask error %#x\n", hr);
881 hr = IRegisteredTask_get_Name(task1, &bstr);
882 ok(hr == S_OK, "get_Name error %#x\n", hr);
883 ok(!lstrcmpW(bstr, Task1), "expected Task1, got %s\n", wine_dbgstr_w(bstr));
884 SysFreeString(bstr);
885 hr = IRegisteredTask_get_Path(task1, &bstr);
886 ok(hr == S_OK, "get_Path error %#x\n", hr);
887 ok(!lstrcmpW(bstr, Wine_Task1), "expected \\Wine\\Task1, got %s\n", wine_dbgstr_w(bstr));
888 SysFreeString(bstr);
889 hr = IRegisteredTask_get_State(task1, &state);
890 ok(hr == S_OK, "get_State error %#x\n", hr);
891 ok(state == TASK_STATE_DISABLED, "expected TASK_STATE_DISABLED, got %d\n", state);
892 hr = IRegisteredTask_get_Enabled(task1, &vbool);
893 ok(hr == S_OK, "get_Enabled error %#x\n", hr);
894 ok(vbool == VARIANT_FALSE, "expected VARIANT_FALSE, got %d\n", vbool);
896 hr = IRegisteredTask_put_Enabled(task1, VARIANT_TRUE);
897 ok(hr == S_OK, "put_Enabled error %#x\n", hr);
898 hr = IRegisteredTask_get_State(task1, &state);
899 ok(hr == S_OK, "get_State error %#x\n", hr);
900 todo_wine
901 ok(state == TASK_STATE_READY, "expected TASK_STATE_READY, got %d\n", state);
902 hr = IRegisteredTask_get_Enabled(task1, &vbool);
903 ok(hr == S_OK, "get_Enabled error %#x\n", hr);
904 todo_wine
905 ok(vbool == VARIANT_TRUE, "expected VARIANT_TRUE, got %d\n", vbool);
907 IRegisteredTask_Release(task1);
909 hr = ITaskFolder_GetTask(folder, Task2, &task2);
910 ok(hr == S_OK, "GetTask error %#x\n", hr);
912 hr = IRegisteredTask_get_Name(task2, &bstr);
913 ok(hr == S_OK, "get_Name error %#x\n", hr);
914 ok(!lstrcmpW(bstr, Task2), "expected Task2, got %s\n", wine_dbgstr_w(bstr));
915 SysFreeString(bstr);
916 hr = IRegisteredTask_get_Path(task2, &bstr);
917 ok(hr == S_OK, "get_Path error %#x\n", hr);
918 ok(!lstrcmpW(bstr, Wine_Task2), "expected \\Wine\\Task2, got %s\n", wine_dbgstr_w(bstr));
919 SysFreeString(bstr);
920 hr = IRegisteredTask_get_State(task2, &state);
921 ok(hr == S_OK, "get_State error %#x\n", hr);
922 todo_wine
923 ok(state == TASK_STATE_READY, "expected TASK_STATE_READY, got %d\n", state);
924 hr = IRegisteredTask_get_Enabled(task2, &vbool);
925 ok(hr == S_OK, "get_Enabled error %#x\n", hr);
926 todo_wine
927 ok(vbool == VARIANT_TRUE, "expected VARIANT_TRUE, got %d\n", vbool);
929 hr = IRegisteredTask_get_State(task2, NULL);
930 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
931 hr = IRegisteredTask_get_Enabled(task2, NULL);
932 ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr);
934 IRegisteredTask_Release(task2);
936 hr = ITaskFolder_DeleteTask(folder, NULL, 0);
937 todo_wine
938 ok(hr == HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY), "expected ERROR_DIR_NOT_EMPTY, got %#x\n", hr);
940 hr = ITaskFolder_DeleteTask(root, Wine_Task1, 0);
941 ok(hr == S_OK, "DeleteTask error %#x\n", hr);
942 hr = ITaskFolder_DeleteTask(folder, Task2, 0);
943 ok(hr == S_OK, "DeleteTask error %#x\n", hr);
945 hr = ITaskFolder_DeleteTask(folder, Task2, 0);
946 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || hr == S_OK /* win7 */, "expected ERROR_FILE_NOT_FOUND, got %#x\n", hr);
948 hr = ITaskFolder_RegisterTask(root, NULL, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
949 if(hr == E_ACCESSDENIED)
951 skip("Access denied\n");
952 goto no_access;
954 ok(hr == S_OK, "RegisterTask error %#x\n", hr);
956 hr = IRegisteredTask_get_Name(task1, &bstr);
957 ok(hr == S_OK, "get_Name error %#x\n", hr);
958 hr = IIDFromString(bstr, &iid);
959 ok(hr == S_OK, "IIDFromString error %#x\n", hr);
961 IRegisteredTask_Release(task1);
963 hr = ITaskFolder_DeleteTask(root, bstr, 0);
964 ok(hr == S_OK, "DeleteTask error %#x\n", hr);
965 SysFreeString(bstr);
967 hr = ITaskFolder_RegisterTask(folder, NULL, xmlW, TASK_CREATE, v_null, v_null, TASK_LOGON_NONE, v_null, &task1);
968 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
970 no_access:
971 ITaskFolder_Release(folder);
973 hr = ITaskFolder_DeleteFolder(root, Wine, 0);
974 ok(hr == S_OK, "DeleteFolder error %#x\n", hr);
976 ITaskFolder_Release(root);
977 ITaskService_Release(service);
980 struct settings
982 WCHAR restart_interval[20];
983 WCHAR execution_time_limit[20];
984 WCHAR delete_expired_task_after[20];
985 int restart_count;
986 int priority;
987 TASK_INSTANCES_POLICY policy;
988 TASK_COMPATIBILITY compatibility;
989 VARIANT_BOOL allow_on_demand_start;
990 VARIANT_BOOL stop_if_going_on_batteries;
991 VARIANT_BOOL disallow_start_if_on_batteries;
992 VARIANT_BOOL allow_hard_terminate;
993 VARIANT_BOOL start_when_available;
994 VARIANT_BOOL run_only_if_network_available;
995 VARIANT_BOOL enabled;
996 VARIANT_BOOL hidden;
997 VARIANT_BOOL run_only_if_idle;
998 VARIANT_BOOL wake_to_run;
1001 /* test the version 1 compatibility settings */
1002 static void test_settings_v1(ITaskDefinition *taskdef, struct settings *test, struct settings *def)
1004 HRESULT hr;
1005 ITaskSettings *set;
1006 int vint;
1007 VARIANT_BOOL vbool;
1008 BSTR bstr;
1009 TASK_INSTANCES_POLICY policy;
1010 TASK_COMPATIBILITY compat;
1012 hr = ITaskDefinition_get_Settings(taskdef, &set);
1013 ok(hr == S_OK, "get_Settings error %#x\n", hr);
1015 hr = ITaskSettings_get_AllowDemandStart(set, &vbool);
1016 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1017 ok(vbool == def->allow_on_demand_start, "expected %d, got %d\n", def->allow_on_demand_start, vbool);
1019 hr = ITaskSettings_get_RestartInterval(set, &bstr);
1020 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1021 if (!def->restart_interval[0])
1022 ok(bstr == NULL, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1023 else
1025 ok(!lstrcmpW(bstr, def->restart_interval), "expected %s, got %s\n", wine_dbgstr_w(def->restart_interval), wine_dbgstr_w(bstr));
1026 SysFreeString(bstr);
1029 hr = ITaskSettings_get_RestartCount(set, &vint);
1030 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1031 ok(vint == def->restart_count, "expected %d, got %d\n", def->restart_count, vint);
1033 hr = ITaskSettings_get_MultipleInstances(set, &policy);
1034 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1035 ok(policy == def->policy, "expected %d, got %d\n", def->policy, policy);
1037 hr = ITaskSettings_get_StopIfGoingOnBatteries(set, &vbool);
1038 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1039 ok(vbool == test->stop_if_going_on_batteries, "expected %d, got %d\n", test->stop_if_going_on_batteries, vbool);
1041 hr = ITaskSettings_get_DisallowStartIfOnBatteries(set, &vbool);
1042 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1043 ok(vbool == test->disallow_start_if_on_batteries, "expected %d, got %d\n", test->disallow_start_if_on_batteries, vbool);
1045 hr = ITaskSettings_get_AllowHardTerminate(set, &vbool);
1046 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1047 ok(vbool == def->allow_hard_terminate, "expected %d, got %d\n", def->allow_hard_terminate, vbool);
1049 hr = ITaskSettings_get_StartWhenAvailable(set, &vbool);
1050 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1051 ok(vbool == def->start_when_available, "expected %d, got %d\n", def->start_when_available, vbool);
1053 hr = ITaskSettings_get_RunOnlyIfNetworkAvailable(set, &vbool);
1054 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1055 ok(vbool == def->run_only_if_network_available, "expected %d, got %d\n", def->run_only_if_network_available, vbool);
1057 hr = ITaskSettings_get_ExecutionTimeLimit(set, &bstr);
1058 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1059 if (!test->execution_time_limit[0])
1060 ok(bstr == NULL, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1061 else
1063 ok(!lstrcmpW(bstr, test->execution_time_limit), "expected %s, got %s\n", wine_dbgstr_w(test->execution_time_limit), wine_dbgstr_w(bstr));
1064 SysFreeString(bstr);
1067 hr = ITaskSettings_get_Enabled(set, &vbool);
1068 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1069 ok(vbool == test->enabled, "expected %d, got %d\n", test->enabled, vbool);
1071 hr = ITaskSettings_get_DeleteExpiredTaskAfter(set, &bstr);
1072 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1073 if (!test->delete_expired_task_after[0])
1074 ok(bstr == NULL, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1075 else
1077 ok(!lstrcmpW(bstr, test->delete_expired_task_after), "expected %s, got %s\n", wine_dbgstr_w(test->delete_expired_task_after), wine_dbgstr_w(bstr));
1078 SysFreeString(bstr);
1081 hr = ITaskSettings_get_Priority(set, &vint);
1082 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1083 ok(vint == test->priority, "expected %d, got %d\n", test->priority, vint);
1085 hr = ITaskSettings_get_Compatibility(set, &compat);
1086 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1087 ok(compat == test->compatibility, "expected %d, got %d\n", test->compatibility, compat);
1089 hr = ITaskSettings_get_Hidden(set, &vbool);
1090 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1091 ok(vbool == test->hidden, "expected %d, got %d\n", test->hidden, vbool);
1093 hr = ITaskSettings_get_RunOnlyIfIdle(set, &vbool);
1094 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1095 ok(vbool == test->run_only_if_idle, "expected %d, got %d\n", test->run_only_if_idle, vbool);
1097 hr = ITaskSettings_get_WakeToRun(set, &vbool);
1098 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1099 ok(vbool == test->wake_to_run, "expected %d, got %d\n", test->wake_to_run, vbool);
1101 /* FIXME: test IIdleSettings and INetworkSettings */
1103 ITaskSettings_Release(set);
1106 static void change_settings(ITaskDefinition *taskdef, struct settings *test)
1108 HRESULT hr;
1109 ITaskSettings *set;
1110 ITriggerCollection *triggers;
1111 IPrincipal *principal;
1112 IActionCollection *actions;
1114 hr = ITaskDefinition_get_Settings(taskdef, &set);
1115 ok(hr == S_OK, "get_Settings error %#x\n", hr);
1117 if (!test->restart_interval[0])
1118 hr = ITaskSettings_put_RestartInterval(set, NULL);
1119 else
1120 hr = ITaskSettings_put_RestartInterval(set, test->restart_interval);
1121 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1123 hr = ITaskSettings_put_RestartCount(set, test->restart_count);
1124 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1126 hr = ITaskSettings_put_MultipleInstances(set, test->policy);
1127 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1129 hr = ITaskSettings_put_StopIfGoingOnBatteries(set, test->stop_if_going_on_batteries);
1130 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1132 hr = ITaskSettings_put_DisallowStartIfOnBatteries(set, test->disallow_start_if_on_batteries);
1133 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1135 hr = ITaskSettings_put_AllowHardTerminate(set, test->allow_hard_terminate);
1136 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1138 hr = ITaskSettings_put_StartWhenAvailable(set, test->start_when_available);
1139 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1141 hr = ITaskSettings_put_RunOnlyIfNetworkAvailable(set, test->run_only_if_network_available);
1142 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1144 if (!test->execution_time_limit[0])
1145 hr = ITaskSettings_put_ExecutionTimeLimit(set, NULL);
1146 else
1147 hr = ITaskSettings_put_ExecutionTimeLimit(set, test->execution_time_limit);
1148 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1150 hr = ITaskSettings_put_Enabled(set, test->enabled);
1151 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1153 if (!test->delete_expired_task_after[0])
1154 hr = ITaskSettings_put_DeleteExpiredTaskAfter(set, NULL);
1155 else
1156 hr = ITaskSettings_put_DeleteExpiredTaskAfter(set, test->delete_expired_task_after);
1157 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1159 hr = ITaskSettings_put_Priority(set, test->priority);
1160 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1162 hr = ITaskSettings_put_Compatibility(set, test->compatibility);
1163 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1165 hr = ITaskSettings_put_Hidden(set, test->hidden);
1166 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1168 hr = ITaskSettings_put_RunOnlyIfIdle(set, test->run_only_if_idle);
1169 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1171 hr = ITaskSettings_put_WakeToRun(set, test->wake_to_run);
1172 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1174 hr = ITaskSettings_put_AllowDemandStart(set, test->allow_on_demand_start);
1175 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1177 triggers = NULL;
1178 hr = ITaskDefinition_get_Triggers(taskdef, &triggers);
1179 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1180 ok(triggers != NULL, "triggers not set\n");
1182 hr = ITaskDefinition_put_Triggers(taskdef, triggers);
1183 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1184 if (triggers) ITriggerCollection_Release(triggers);
1186 principal = NULL;
1187 hr = ITaskDefinition_get_Principal(taskdef, &principal);
1188 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1189 ok(principal != NULL, "principal not set\n");
1191 hr = ITaskDefinition_put_Principal(taskdef, principal);
1192 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1193 if (principal) IPrincipal_Release(principal);
1195 actions = NULL;
1196 hr = ITaskDefinition_get_Actions(taskdef, &actions);
1197 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1198 ok(actions != NULL, "actions not set\n");
1200 hr = ITaskDefinition_put_Actions(taskdef, actions);
1201 ok(hr == S_OK, "expected S_OK, got %#x\n", hr);
1202 if (actions) IActionCollection_Release(actions);
1204 /* FIXME: set IIdleSettings and INetworkSettings */
1206 ITaskSettings_Release(set);
1209 static void test_daily_trigger(ITrigger *trigger)
1211 static const WCHAR startW[] =
1212 {'2','0','0','4','-','0','1','-','0','1','T','0','0',':','0','0',':','0','0',0};
1213 static const WCHAR start2W[] =
1214 {'2','0','0','4','-','0','1','-','0','1','T','0','0',':','0','0',':','0','0','Z',0};
1215 static const WCHAR start3W[] =
1216 {'2','0','0','4','-','0','1','-','0','1','T','0','0',':','0','0',':','0','0','+','0','1',':','0','0',0};
1217 static const WCHAR start4W[] =
1218 {'2','0','0','4','.','0','1','.','0','1','T','0','0','.','0','0','.','0','0',0};
1219 static const WCHAR start5W[] =
1220 {'9','9','9','9','-','9','9','-','9','9','T','9','9',':','9','9',':','9','9',0};
1221 static const WCHAR start6W[] =
1222 {'i','n','v','a','l','i','d',0};
1223 static const struct
1225 const WCHAR *str;
1226 HRESULT hr;
1228 start_test[] =
1230 {startW, S_OK},
1231 {start2W, S_OK},
1232 {start3W, S_OK},
1233 {start4W, S_OK},
1234 {start5W, S_OK},
1235 {start6W, S_OK},
1237 IDailyTrigger *daily_trigger;
1238 BSTR start_boundary;
1239 VARIANT_BOOL enabled;
1240 short interval;
1241 HRESULT hr;
1242 ULONG i;
1244 hr = ITrigger_QueryInterface(trigger, &IID_IDailyTrigger, (void**)&daily_trigger);
1245 ok(hr == S_OK, "Could not get IDailyTrigger iface: %08x\n", hr);
1247 interval = -1;
1248 hr = IDailyTrigger_get_DaysInterval(daily_trigger, &interval);
1249 ok(hr == S_OK, "get_DaysInterval failed: %08x\n", hr);
1250 ok(interval == 1, "interval = %d\n", interval);
1252 hr = IDailyTrigger_put_DaysInterval(daily_trigger, -2);
1253 ok(hr == E_INVALIDARG, "put_DaysInterval failed: %08x\n", hr);
1254 hr = IDailyTrigger_put_DaysInterval(daily_trigger, 0);
1255 ok(hr == E_INVALIDARG, "put_DaysInterval failed: %08x\n", hr);
1257 interval = -1;
1258 hr = IDailyTrigger_get_DaysInterval(daily_trigger, &interval);
1259 ok(hr == S_OK, "get_DaysInterval failed: %08x\n", hr);
1260 ok(interval == 1, "interval = %d\n", interval);
1262 hr = IDailyTrigger_put_DaysInterval(daily_trigger, 2);
1263 ok(hr == S_OK, "put_DaysInterval failed: %08x\n", hr);
1265 interval = -1;
1266 hr = IDailyTrigger_get_DaysInterval(daily_trigger, &interval);
1267 ok(hr == S_OK, "get_DaysInterval failed: %08x\n", hr);
1268 ok(interval == 2, "interval = %d\n", interval);
1270 hr = IDailyTrigger_get_StartBoundary(daily_trigger, NULL);
1271 ok(hr == E_POINTER, "get_StartBoundary failed: %08x\n", hr);
1273 start_boundary = (BSTR)0xdeadbeef;
1274 hr = IDailyTrigger_get_StartBoundary(daily_trigger, &start_boundary);
1275 ok(hr == S_OK, "get_StartBoundary failed: %08x\n", hr);
1276 ok(start_boundary == NULL, "start_boundary not set\n");
1278 for (i = 0; i < ARRAY_SIZE(start_test); i++)
1280 start_boundary = SysAllocString(start_test[i].str);
1281 hr = IDailyTrigger_put_StartBoundary(daily_trigger, start_boundary);
1282 ok(hr == start_test[i].hr, "%u: got %08x expected %08x\n", i, hr, start_test[i].hr);
1283 SysFreeString(start_boundary);
1284 if (hr == S_OK)
1286 start_boundary = NULL;
1287 hr = IDailyTrigger_get_StartBoundary(daily_trigger, &start_boundary);
1288 ok(hr == S_OK, "%u: got %08x\n", i, hr);
1289 ok(start_boundary != NULL, "start_boundary not set\n");
1290 ok(!lstrcmpW(start_boundary, start_test[i].str), "%u: got %s\n", i, wine_dbgstr_w(start_boundary));
1291 SysFreeString(start_boundary);
1295 hr = IDailyTrigger_put_StartBoundary(daily_trigger, NULL);
1296 ok(hr == S_OK, "put_StartBoundary failed: %08x\n", hr);
1298 hr = IDailyTrigger_get_Enabled(daily_trigger, NULL);
1299 ok(hr == E_POINTER, "get_Enabled failed: %08x\n", hr);
1301 enabled = VARIANT_FALSE;
1302 hr = IDailyTrigger_get_Enabled(daily_trigger, &enabled);
1303 ok(hr == S_OK, "get_Enabled failed: %08x\n", hr);
1304 ok(enabled == VARIANT_TRUE, "got %d\n", enabled);
1306 hr = IDailyTrigger_put_Enabled(daily_trigger, VARIANT_FALSE);
1307 ok(hr == S_OK, "put_Enabled failed: %08x\n", hr);
1309 enabled = VARIANT_TRUE;
1310 hr = IDailyTrigger_get_Enabled(daily_trigger, &enabled);
1311 ok(hr == S_OK, "get_Enabled failed: %08x\n", hr);
1312 ok(enabled == VARIANT_FALSE, "got %d\n", enabled);
1314 IDailyTrigger_Release(daily_trigger);
1317 static void create_action(ITaskDefinition *taskdef)
1319 static WCHAR task1_exe[] = { 't','a','s','k','1','.','e','x','e',0 };
1320 static WCHAR workdir[] = { 'w','o','r','k','d','i','r',0 };
1321 static WCHAR args[] = { 'a','r','g','u','m','e','n','s',0 };
1322 static WCHAR comment[] = { 'c','o','m','m','e','n','t',0 };
1323 HRESULT hr;
1324 IActionCollection *actions;
1325 IAction *action;
1326 IExecAction *exec_action;
1327 TASK_ACTION_TYPE type;
1328 BSTR path, str;
1330 hr = ITaskDefinition_get_Actions(taskdef, NULL);
1331 ok(hr == E_POINTER, "got %#x\n", hr);
1333 hr = ITaskDefinition_get_Actions(taskdef, &actions);
1334 ok(hr == S_OK, "get_Actions error %#x\n", hr);
1336 hr = IActionCollection_Create(actions, TASK_ACTION_EXEC, &action);
1337 ok(hr == S_OK, "Create action error %#x\n", hr);
1339 hr = IAction_QueryInterface(action, &IID_IExecAction, (void **)&exec_action);
1340 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1342 type = 0xdeadbeef;
1343 hr = IExecAction_get_Type(exec_action, &type);
1344 ok(hr == S_OK, "get_Type error %#x\n", hr);
1345 ok(type == TASK_ACTION_EXEC, "got %u\n", type );
1347 hr = IExecAction_get_Path(exec_action, NULL);
1348 ok(hr == E_POINTER, "got %#x\n", hr);
1350 path = (BSTR)0xdeadbeef;
1351 hr = IExecAction_get_Path(exec_action, &path);
1352 ok(hr == S_OK, "get_Path error %#x\n", hr);
1353 ok(path == NULL, "path not set\n");
1355 hr = IExecAction_put_Path(exec_action, NULL);
1356 ok(hr == S_OK, "put_Path error %#x\n", hr);
1358 hr = IExecAction_put_Path(exec_action, task1_exe);
1359 ok(hr == S_OK, "put_Path error %#x\n", hr);
1361 path = NULL;
1362 hr = IExecAction_get_Path(exec_action, &path);
1363 ok(hr == S_OK, "get_Path error %#x\n", hr);
1364 ok(path != NULL, "path not set\n");
1365 ok(!lstrcmpW(path, task1_exe), "got %s\n", wine_dbgstr_w(path));
1366 SysFreeString(path);
1368 hr = IExecAction_get_WorkingDirectory(exec_action, NULL);
1369 ok(hr == E_POINTER, "got %#x\n", hr);
1371 path = (BSTR)0xdeadbeef;
1372 hr = IExecAction_get_WorkingDirectory(exec_action, &path);
1373 ok(hr == S_OK, "get_WorkingDirectory error %#x\n", hr);
1374 ok(path == NULL, "workdir not set\n");
1376 hr = IExecAction_put_WorkingDirectory(exec_action, NULL);
1377 ok(hr == S_OK, "put_WorkingDirectory error %#x\n", hr);
1379 hr = IExecAction_put_WorkingDirectory(exec_action, workdir);
1380 ok(hr == S_OK, "put_WorkingDirectory error %#x\n", hr);
1382 path = NULL;
1383 hr = IExecAction_get_WorkingDirectory(exec_action, &path);
1384 ok(hr == S_OK, "get_WorkingDirectory error %#x\n", hr);
1385 ok(path != NULL, "workdir not set\n");
1386 ok(!lstrcmpW(path, workdir), "got %s\n", wine_dbgstr_w(path));
1387 SysFreeString(path);
1389 hr = IExecAction_get_Arguments(exec_action, NULL);
1390 ok(hr == E_POINTER, "got %#x\n", hr);
1392 path = (BSTR)0xdeadbeef;
1393 hr = IExecAction_get_Arguments(exec_action, &path);
1394 ok(hr == S_OK, "get_Arguments error %#x\n", hr);
1395 ok(path == NULL, "args not set\n");
1397 hr = IExecAction_put_Arguments(exec_action, NULL);
1398 ok(hr == S_OK, "put_Arguments error %#x\n", hr);
1400 hr = IExecAction_put_Arguments(exec_action, args);
1401 ok(hr == S_OK, "put_Arguments error %#x\n", hr);
1403 path = NULL;
1404 hr = IExecAction_get_Arguments(exec_action, &path);
1405 ok(hr == S_OK, "get_Arguments error %#x\n", hr);
1406 ok(path != NULL, "args not set\n");
1407 ok(!lstrcmpW(path, args), "got %s\n", wine_dbgstr_w(path));
1408 SysFreeString(path);
1411 str = (BSTR)0xdeadbeef;
1412 hr = IExecAction_get_Id(exec_action, &str);
1413 ok(hr == S_OK, "get_Id error %#x\n", hr);
1414 ok(str == NULL, "id should be NULL\n");
1416 hr = IExecAction_put_Id(exec_action, NULL);
1417 ok(hr == S_OK, "put_Id error %#x\n", hr);
1419 hr = IExecAction_put_Id(exec_action, comment);
1420 ok(hr == S_OK, "put_Id error %#x\n", hr);
1422 str = NULL;
1423 hr = IExecAction_get_Id(exec_action, &str);
1424 ok(hr == S_OK, "get_Id error %#x\n", hr);
1425 ok(str != NULL, "should not be NULL\n");
1426 ok(!lstrcmpW(str, comment), "got %s\n", wine_dbgstr_w(str));
1427 SysFreeString(str);
1429 IExecAction_Release(exec_action);
1430 IAction_Release(action);
1431 IActionCollection_Release(actions);
1434 static void test_TaskDefinition(void)
1436 static const char xml1[] =
1437 "<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n"
1438 " <RegistrationInfo>\n"
1439 " <Description>\"Task1\"</Description>\n"
1440 " <Author>author</Author>\n"
1441 " <Version>1.0</Version>\n"
1442 " <Date>2018-04-02T11:22:33</Date>\n"
1443 " <Documentation>doc</Documentation>\n"
1444 " <URI>uri</URI>\n"
1445 " <Source>source</Source>\n"
1446 " </RegistrationInfo>\n"
1447 " <Settings>\n"
1448 " <Enabled>false</Enabled>\n"
1449 " <Hidden>false</Hidden>\n"
1450 " </Settings>\n"
1451 " <Actions>\n"
1452 " <Exec>\n"
1453 " <Command>\"task1.exe\"</Command>\n"
1454 " </Exec>\n"
1455 " </Actions>\n"
1456 "</Task>\n";
1457 static const char xml2[] =
1458 "<Task>\n"
1459 " <RegistrationInfo>\n"
1460 " <Description>\"Task1\"</Description>\n"
1461 " </RegistrationInfo>\n"
1462 " <Settings>\n"
1463 " <Enabled>false</Enabled>\n"
1464 " <Hidden>false</Hidden>\n"
1465 " </Settings>\n"
1466 " <Actions>\n"
1467 " <Exec>\n"
1468 " <Command>\"task1.exe\"</Command>\n"
1469 " </Exec>\n"
1470 " </Actions>\n"
1471 "</Task>\n";
1472 static const char xml3[] =
1473 "<TASK>\n"
1474 " <RegistrationInfo>\n"
1475 " <Description>\"Task1\"</Description>\n"
1476 " </RegistrationInfo>\n"
1477 " <Settings>\n"
1478 " <Enabled>false</Enabled>\n"
1479 " <Hidden>false</Hidden>\n"
1480 " </Settings>\n"
1481 " <Actions>\n"
1482 " <Exec>\n"
1483 " <Command>\"task1.exe\"</Command>\n"
1484 " </Exec>\n"
1485 " </Actions>\n"
1486 "</TASK>\n";
1487 static const char xml4[] =
1488 "<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n"
1489 " <RegistrationInfo/>\n"
1490 " <Settings/>\n"
1491 " <Actions>\n"
1492 " <Exec>\n"
1493 " <Command>\"task1.exe\"</Command>\n"
1494 " </Exec>\n"
1495 " </Actions>\n"
1496 "</Task>\n";
1497 static const char xml5[] =
1498 "<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n"
1499 " <RegistrationInfo/>\n"
1500 " <Settings/>\n"
1501 " <Actions/>\n"
1502 "</Task>\n";
1503 static const char xml6[] =
1504 "<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n"
1505 " <RegistrationInfo/>\n"
1506 " <Actions>\n"
1507 " <Exec>\n"
1508 " <Command>\"task1.exe\"</Command>\n"
1509 " </Exec>\n"
1510 " </Actions>\n"
1511 " <Settings>\n"
1512 "</Task>\n";
1513 static const char xml7[] =
1514 "<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n"
1515 " <RegistrationInfo/>\n"
1516 " <Settings>\n"
1517 " <Enabled>FALSE</Enabled>\n"
1518 " </Settings>\n"
1519 " <Actions>\n"
1520 " <Exec>\n"
1521 " <Command>\"task1.exe\"</Command>\n"
1522 " </Exec>\n"
1523 " </Actions>\n"
1524 "</Task>\n";
1525 static const WCHAR authorW[] = { 'a','u','t','h','o','r',0 };
1526 static const WCHAR versionW[] = { '1','.','0',0 };
1527 static const WCHAR dateW[] = { '2','0','1','8','-','0','4','-','0','2','T','1','1',':','2','2',':','3','3',0 };
1528 static const WCHAR docW[] = { 'd','o','c',0 };
1529 static const WCHAR uriW[] = { 'u','r','i',0 };
1530 static const WCHAR sourceW[] = { 's','o','u','r','c','e',0 };
1531 static WCHAR Task1[] = { '"','T','a','s','k','1','"',0 };
1532 static struct settings def_settings = { { 0 }, { 'P','T','7','2','H',0 }, { 0 },
1533 0, 7, TASK_INSTANCES_IGNORE_NEW, TASK_COMPATIBILITY_V2, VARIANT_TRUE, VARIANT_TRUE,
1534 VARIANT_TRUE, VARIANT_TRUE, VARIANT_FALSE, VARIANT_FALSE, VARIANT_TRUE, VARIANT_FALSE,
1535 VARIANT_FALSE, VARIANT_FALSE };
1536 static struct settings new_settings = { { 'P','1','Y',0 }, { 'P','T','1','0','M',0 }, { 0 },
1537 100, 1, TASK_INSTANCES_STOP_EXISTING, TASK_COMPATIBILITY_V1, VARIANT_FALSE, VARIANT_FALSE,
1538 VARIANT_FALSE, VARIANT_FALSE, VARIANT_TRUE, VARIANT_TRUE, VARIANT_FALSE, VARIANT_TRUE,
1539 VARIANT_TRUE, VARIANT_TRUE };
1540 ITriggerCollection *trigger_col, *trigger_col2;
1541 HRESULT hr;
1542 ITaskService *service;
1543 ITaskDefinition *taskdef;
1544 IRegistrationInfo *reginfo;
1545 ITrigger *trigger;
1546 BSTR xml, bstr;
1547 VARIANT var;
1548 WCHAR xmlW[sizeof(xml1)];
1550 hr = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void **)&service);
1551 if (hr != S_OK)
1553 win_skip("CoCreateInstance(CLSID_TaskScheduler) error %#x\n", hr);
1554 return;
1557 hr = ITaskService_NewTask(service, 0, &taskdef);
1558 ok(hr == S_OK, "NewTask error %#x\n", hr);
1560 test_settings_v1(taskdef, &def_settings, &def_settings);
1561 change_settings(taskdef, &new_settings);
1563 /* Action is mandatory for v1 compatibility */
1564 create_action(taskdef);
1566 hr = ITaskDefinition_get_XmlText(taskdef, &xml);
1567 ok(hr == S_OK, "get_XmlText error %#x\n", hr);
1569 ITaskDefinition_Release(taskdef);
1571 hr = ITaskService_NewTask(service, 0, &taskdef);
1572 ok(hr == S_OK, "NewTask error %#x\n", hr);
1574 hr = ITaskDefinition_put_XmlText(taskdef, xml);
1575 ok(hr == S_OK, "put_XmlText error %#x\n", hr);
1576 SysFreeString(xml);
1578 /* FIXME: uncomment once changing settings is implemented
1579 test_settings_v1(taskdef, &new_settings, &def_settings);
1582 hr = ITaskDefinition_put_XmlText(taskdef, NULL);
1583 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1585 MultiByteToWideChar(CP_ACP, 0, xml1, -1, xmlW, ARRAY_SIZE(xmlW));
1586 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1587 ok(hr == S_OK, "put_XmlText error %#x\n", hr);
1589 MultiByteToWideChar(CP_ACP, 0, xml2, -1, xmlW, ARRAY_SIZE(xmlW));
1590 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1591 ok(hr == SCHED_E_NAMESPACE, "expected SCHED_E_NAMESPACE, got %#x\n", hr);
1593 MultiByteToWideChar(CP_ACP, 0, xml3, -1, xmlW, ARRAY_SIZE(xmlW));
1594 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1595 todo_wine
1596 ok(hr == SCHED_E_UNEXPECTEDNODE, "expected SCHED_E_UNEXPECTEDNODE, got %#x\n", hr);
1598 MultiByteToWideChar(CP_ACP, 0, xml4, -1, xmlW, ARRAY_SIZE(xmlW));
1599 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1600 ok(hr == S_OK, "put_XmlText error %#x\n", hr);
1602 MultiByteToWideChar(CP_ACP, 0, xml5, -1, xmlW, ARRAY_SIZE(xmlW));
1603 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1604 todo_wine
1605 ok(hr == SCHED_E_MISSINGNODE, "expected SCHED_E_MISSINGNODE, got %#x\n", hr);
1607 MultiByteToWideChar(CP_ACP, 0, xml6, -1, xmlW, ARRAY_SIZE(xmlW));
1608 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1609 ok(hr == SCHED_E_MALFORMEDXML, "expected SCHED_E_MALFORMEDXML, got %#x\n", hr);
1611 MultiByteToWideChar(CP_ACP, 0, xml7, -1, xmlW, ARRAY_SIZE(xmlW));
1612 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1613 ok(hr == SCHED_E_INVALIDVALUE, "expected SCHED_E_INVALIDVALUE, got %#x\n", hr);
1615 xmlW[0] = 0;
1616 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1617 ok(hr == SCHED_E_MALFORMEDXML, "expected SCHED_E_MALFORMEDXML, got %#x\n", hr);
1619 /* test registration info */
1620 MultiByteToWideChar(CP_ACP, 0, xml1, -1, xmlW, ARRAY_SIZE(xmlW));
1621 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1622 ok(hr == S_OK, "put_XmlText error %#x\n", hr);
1623 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &reginfo);
1624 ok(hr == S_OK, "get_RegistrationInfo error %#x\n", hr);
1626 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
1627 ok(hr == S_OK, "get_Description error %#x\n", hr);
1628 ok(!lstrcmpW(bstr, Task1), "expected Task1, got %s\n", wine_dbgstr_w(bstr));
1629 SysFreeString(bstr);
1630 hr = IRegistrationInfo_put_Description(reginfo, NULL);
1631 ok(hr == S_OK, "put_Description error %#x\n", hr);
1632 bstr = (BSTR)0xdeadbeef;
1633 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
1634 ok(hr == S_OK, "get_Description error %#x\n", hr);
1635 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1637 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
1638 ok(hr == S_OK, "get_Author error %#x\n", hr);
1639 ok(!lstrcmpW(bstr, authorW), "expected %s, got %s\n", wine_dbgstr_w(authorW), wine_dbgstr_w(bstr));
1640 SysFreeString(bstr);
1641 hr = IRegistrationInfo_put_Author(reginfo, NULL);
1642 ok(hr == S_OK, "put_Author error %#x\n", hr);
1643 bstr = (BSTR)0xdeadbeef;
1644 hr = IRegistrationInfo_get_Author(reginfo, &bstr);
1645 ok(hr == S_OK, "get_Author error %#x\n", hr);
1646 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1648 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
1649 ok(hr == S_OK, "get_Version error %#x\n", hr);
1650 ok(!lstrcmpW(bstr, versionW), "expected %s, got %s\n", wine_dbgstr_w(versionW), wine_dbgstr_w(bstr));
1651 SysFreeString(bstr);
1652 hr = IRegistrationInfo_put_Version(reginfo, NULL);
1653 ok(hr == S_OK, "put_Version error %#x\n", hr);
1654 bstr = (BSTR)0xdeadbeef;
1655 hr = IRegistrationInfo_get_Version(reginfo, &bstr);
1656 ok(hr == S_OK, "get_Version error %#x\n", hr);
1657 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1659 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
1660 ok(hr == S_OK, "get_Date error %#x\n", hr);
1661 ok(!lstrcmpW(bstr, dateW), "expected %s, got %s\n", wine_dbgstr_w(dateW), wine_dbgstr_w(bstr));
1662 SysFreeString(bstr);
1663 hr = IRegistrationInfo_put_Date(reginfo, NULL);
1664 ok(hr == S_OK, "put_Date error %#x\n", hr);
1665 bstr = (BSTR)0xdeadbeef;
1666 hr = IRegistrationInfo_get_Date(reginfo, &bstr);
1667 ok(hr == S_OK, "get_Date error %#x\n", hr);
1668 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1670 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
1671 ok(hr == S_OK, "get_Documentation error %#x\n", hr);
1672 ok(!lstrcmpW(bstr, docW), "expected %s, got %s\n", wine_dbgstr_w(docW), wine_dbgstr_w(bstr));
1673 SysFreeString(bstr);
1674 hr = IRegistrationInfo_put_Documentation(reginfo, NULL);
1675 ok(hr == S_OK, "put_Documentation error %#x\n", hr);
1676 bstr = (BSTR)0xdeadbeef;
1677 hr = IRegistrationInfo_get_Documentation(reginfo, &bstr);
1678 ok(hr == S_OK, "get_Documentation error %#x\n", hr);
1679 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1681 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
1682 ok(hr == S_OK, "get_URI error %#x\n", hr);
1683 ok(!lstrcmpW(bstr, uriW), "expected %s, got %s\n", wine_dbgstr_w(uriW), wine_dbgstr_w(bstr));
1684 SysFreeString(bstr);
1685 hr = IRegistrationInfo_put_URI(reginfo, NULL);
1686 ok(hr == S_OK, "put_URI error %#x\n", hr);
1687 bstr = (BSTR)0xdeadbeef;
1688 hr = IRegistrationInfo_get_URI(reginfo, &bstr);
1689 ok(hr == S_OK, "get_URI error %#x\n", hr);
1690 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1692 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
1693 ok(hr == S_OK, "get_Source error %#x\n", hr);
1694 ok(!lstrcmpW(bstr, sourceW), "expected %s, got %s\n", wine_dbgstr_w(sourceW), wine_dbgstr_w(bstr));
1695 SysFreeString(bstr);
1696 hr = IRegistrationInfo_put_Source(reginfo, NULL);
1697 ok(hr == S_OK, "put_Source error %#x\n", hr);
1698 bstr = (BSTR)0xdeadbeef;
1699 hr = IRegistrationInfo_get_Source(reginfo, &bstr);
1700 ok(hr == S_OK, "get_Source error %#x\n", hr);
1701 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1703 V_VT(&var) = VT_BSTR;
1704 V_BSTR(&var) = NULL;
1705 hr = IRegistrationInfo_get_SecurityDescriptor(reginfo, &var);
1706 todo_wine
1707 ok(hr == S_OK, "get_SecurityDescriptor error %#x\n", hr);
1708 if (hr == S_OK)
1709 ok(V_VT(&var) == VT_EMPTY, "expected VT_EMPTY, got %u\n", V_VT(&var));
1711 IRegistrationInfo_Release(reginfo);
1713 MultiByteToWideChar(CP_ACP, 0, xml4, -1, xmlW, ARRAY_SIZE(xmlW));
1714 hr = ITaskDefinition_put_XmlText(taskdef, xmlW);
1715 ok(hr == S_OK, "put_XmlText error %#x\n", hr);
1716 hr = ITaskDefinition_get_RegistrationInfo(taskdef, &reginfo);
1717 ok(hr == S_OK, "get_RegistrationInfo error %#x\n", hr);
1719 hr = IRegistrationInfo_get_Description(reginfo, &bstr);
1720 ok(hr == S_OK, "get_Description error %#x\n", hr);
1721 ok(!bstr, "expected NULL, got %s\n", wine_dbgstr_w(bstr));
1723 hr = ITaskDefinition_get_Triggers(taskdef, &trigger_col);
1724 ok(hr == S_OK, "get_Triggers failed: %08x\n", hr);
1725 ok(trigger_col != NULL, "Triggers = NULL\n");
1727 hr = ITriggerCollection_Create(trigger_col, TASK_TRIGGER_DAILY, &trigger);
1728 ok(hr == S_OK, "Create failed: %08x\n", hr);
1729 ok(trigger != NULL, "trigger = NULL\n");
1730 test_daily_trigger(trigger);
1731 ITrigger_Release(trigger);
1732 ITriggerCollection_Release(trigger_col);
1734 hr = ITaskDefinition_get_Triggers(taskdef, &trigger_col2);
1735 ok(hr == S_OK, "get_Triggers failed: %08x\n", hr);
1736 ok(trigger_col == trigger_col2, "Mismatched triggers\n");
1737 ITriggerCollection_Release(trigger_col2);
1739 IRegistrationInfo_Release(reginfo);
1740 ITaskDefinition_Release(taskdef);
1741 ITaskService_Release(service);
1744 START_TEST(scheduler)
1746 OleInitialize(NULL);
1748 test_Connect();
1749 test_GetFolder();
1750 test_FolderCollection();
1751 test_GetTask();
1752 test_TaskDefinition();
1754 OleUninitialize();