2 * Copyright 2012 Detlef Riekenberg
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
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(schtasks
);
28 static ITaskFolder
*get_tasks_root_folder(void)
30 ITaskService
*service
;
35 hres
= CoCreateInstance(&CLSID_TaskScheduler
, NULL
, CLSCTX_INPROC_SERVER
,
36 &IID_ITaskService
, (void**)&service
);
40 V_VT(&empty
) = VT_EMPTY
;
41 hres
= ITaskService_Connect(service
, empty
, empty
, empty
, empty
);
43 FIXME("Connect failed: %08x\n", hres
);
47 hres
= ITaskService_GetFolder(service
, NULL
, &root
);
48 ITaskService_Release(service
);
50 FIXME("GetFolder failed: %08x\n", hres
);
57 static IRegisteredTask
*get_registered_task(const WCHAR
*name
)
59 IRegisteredTask
*registered_task
;
64 root
= get_tasks_root_folder();
68 str
= SysAllocString(name
);
69 hres
= ITaskFolder_GetTask(root
, str
, ®istered_task
);
71 ITaskFolder_Release(root
);
73 FIXME("GetTask failed: %08x\n", hres
);
77 return registered_task
;
80 static BSTR
read_file_to_bstr(const WCHAR
*file_name
)
82 LARGE_INTEGER file_size
;
83 DWORD read_size
, size
;
89 file
= CreateFileW(file_name
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
90 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
91 if (file
== INVALID_HANDLE_VALUE
) {
92 FIXME("Could not open file\n");
96 if (!GetFileSizeEx(file
, &file_size
) || !file_size
.QuadPart
) {
97 FIXME("Empty file\n");
102 data
= HeapAlloc(GetProcessHeap(), 0, file_size
.QuadPart
);
104 r
= ReadFile(file
, data
, file_size
.QuadPart
, &read_size
, NULL
);
107 FIXME("Read filed\n");
108 HeapFree(GetProcessHeap(), 0, data
);
112 if (read_size
> 2 && data
[0] == 0xff && data
[1] == 0xfe) { /* UTF-16 BOM */
113 ret
= SysAllocStringLen((const WCHAR
*)(data
+ 2), (read_size
- 2) / sizeof(WCHAR
));
115 size
= MultiByteToWideChar(CP_ACP
, 0, (const char *)data
, read_size
, NULL
, 0);
116 ret
= SysAllocStringLen(NULL
, size
);
118 MultiByteToWideChar(CP_ACP
, 0, (const char *)data
, read_size
, ret
, size
);
120 HeapFree(GetProcessHeap(), 0, data
);
125 static int change_command(int argc
, WCHAR
*argv
[])
127 BOOL have_option
= FALSE
, enable
= FALSE
;
128 const WCHAR
*task_name
= NULL
;
129 IRegisteredTask
*task
;
133 if (!wcsicmp(argv
[0], L
"/tn")) {
135 FIXME("Missing /tn value\n");
140 FIXME("Duplicated /tn argument\n");
147 } else if (!wcsicmp(argv
[0], L
"/enable")) {
152 } else if (!wcsicmp(argv
[0], L
"/tr")) {
154 FIXME("Missing /tr value\n");
158 FIXME("Unsupported /tr option %s\n", debugstr_w(argv
[1]));
163 FIXME("Unsupported arguments %s\n", debugstr_w(argv
[0]));
169 FIXME("Missing /tn option\n");
174 FIXME("Missing change options\n");
178 task
= get_registered_task(task_name
);
183 hres
= IRegisteredTask_put_Enabled(task
, VARIANT_TRUE
);
185 IRegisteredTask_Release(task
);
186 FIXME("put_Enabled failed: %08x\n", hres
);
191 IRegisteredTask_Release(task
);
195 static int create_command(int argc
, WCHAR
*argv
[])
197 const WCHAR
*task_name
= NULL
, *xml_file
= NULL
;
198 ITaskFolder
*root
= NULL
;
199 LONG flags
= TASK_CREATE
;
200 IRegisteredTask
*task
;
206 if (!wcsicmp(argv
[0], L
"/xml")) {
208 FIXME("Missing /xml value\n");
213 FIXME("Duplicated /xml argument\n");
220 } else if (!wcsicmp(argv
[0], L
"/tn")) {
222 FIXME("Missing /tn value\n");
227 FIXME("Duplicated /tn argument\n");
234 } else if (!wcsicmp(argv
[0], L
"/f")) {
235 flags
= TASK_CREATE_OR_UPDATE
;
238 } else if (!wcsicmp(argv
[0], L
"/ru")) {
240 FIXME("Missing /ru value\n");
244 FIXME("Unsupported /ru option %s\n", debugstr_w(argv
[1]));
248 FIXME("Unsupported argument %s\n", debugstr_w(argv
[0]));
254 FIXME("Missing /tn argument\n");
259 FIXME("Missing /xml argument\n");
263 xml
= read_file_to_bstr(xml_file
);
267 root
= get_tasks_root_folder();
273 V_VT(&empty
) = VT_EMPTY
;
274 str
= SysAllocString(task_name
);
275 hres
= ITaskFolder_RegisterTask(root
, str
, xml
, flags
, empty
, empty
,
276 TASK_LOGON_NONE
, empty
, &task
);
279 ITaskFolder_Release(root
);
283 IRegisteredTask_Release(task
);
287 static int delete_command(int argc
, WCHAR
*argv
[])
289 const WCHAR
*task_name
= NULL
;
290 ITaskFolder
*root
= NULL
;
295 if (!wcsicmp(argv
[0], L
"/f")) {
296 TRACE("force opt\n");
299 } else if (!wcsicmp(argv
[0], L
"/tn")) {
301 FIXME("Missing /tn value\n");
306 FIXME("Duplicated /tn argument\n");
314 FIXME("Unsupported argument %s\n", debugstr_w(argv
[0]));
320 FIXME("Missing /tn argument\n");
324 root
= get_tasks_root_folder();
328 str
= SysAllocString(task_name
);
329 hres
= ITaskFolder_DeleteTask(root
, str
, 0);
331 ITaskFolder_Release(root
);
338 int __cdecl
wmain(int argc
, WCHAR
*argv
[])
342 for (i
= 0; i
< argc
; i
++)
343 TRACE(" %s", wine_dbgstr_w(argv
[i
]));
349 FIXME("Print current tasks state\n");
350 else if (!wcsicmp(argv
[1], L
"/change"))
351 ret
= change_command(argc
- 2, argv
+ 2);
352 else if (!wcsicmp(argv
[1], L
"/create"))
353 ret
= create_command(argc
- 2, argv
+ 2);
354 else if (!wcsicmp(argv
[1], L
"/delete"))
355 ret
= delete_command(argc
- 2, argv
+ 2);
357 FIXME("Unsupported command %s\n", debugstr_w(argv
[1]));