include: Fix ASM_CFI definition.
[wine.git] / programs / schtasks / schtasks.c
blob980093e7331a35764792854f8e7629ce88e902bb
1 /*
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
19 #define COBJMACROS
21 #include "initguid.h"
22 #include "taskschd.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(schtasks);
28 static const WCHAR change_optW[] = {'/','c','h','a','n','g','e',0};
29 static const WCHAR create_optW[] = {'/','c','r','e','a','t','e',0};
30 static const WCHAR delete_optW[] = {'/','d','e','l','e','t','e',0};
31 static const WCHAR enable_optW[] = {'/','e','n','a','b','l','e',0};
32 static const WCHAR f_optW[] = {'/','f',0};
33 static const WCHAR ru_optW[] = {'/','r','u',0};
34 static const WCHAR tn_optW[] = {'/','t','n',0};
35 static const WCHAR tr_optW[] = {'/','t','r',0};
36 static const WCHAR xml_optW[] = {'/','x','m','l',0};
38 static ITaskFolder *get_tasks_root_folder(void)
40 ITaskService *service;
41 ITaskFolder *root;
42 VARIANT empty;
43 HRESULT hres;
45 hres = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER,
46 &IID_ITaskService, (void**)&service);
47 if (FAILED(hres))
48 return NULL;
50 V_VT(&empty) = VT_EMPTY;
51 hres = ITaskService_Connect(service, empty, empty, empty, empty);
52 if (FAILED(hres)) {
53 FIXME("Connect failed: %08x\n", hres);
54 return NULL;
57 hres = ITaskService_GetFolder(service, NULL, &root);
58 ITaskService_Release(service);
59 if (FAILED(hres)) {
60 FIXME("GetFolder failed: %08x\n", hres);
61 return NULL;
64 return root;
67 static IRegisteredTask *get_registered_task(const WCHAR *name)
69 IRegisteredTask *registered_task;
70 ITaskFolder *root;
71 BSTR str;
72 HRESULT hres;
74 root = get_tasks_root_folder();
75 if (!root)
76 return NULL;
78 str = SysAllocString(name);
79 hres = ITaskFolder_GetTask(root, str, &registered_task);
80 SysFreeString(str);
81 ITaskFolder_Release(root);
82 if (FAILED(hres)) {
83 FIXME("GetTask failed: %08x\n", hres);
84 return NULL;
87 return registered_task;
90 static BSTR read_file_to_bstr(const WCHAR *file_name)
92 LARGE_INTEGER file_size;
93 DWORD read_size, size;
94 unsigned char *data;
95 HANDLE file;
96 BOOL r = FALSE;
97 BSTR ret;
99 file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
100 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
101 if (file == INVALID_HANDLE_VALUE) {
102 FIXME("Could not open file\n");
103 return NULL;
106 if (!GetFileSizeEx(file, &file_size) || !file_size.QuadPart) {
107 FIXME("Empty file\n");
108 CloseHandle(file);
109 return NULL;
112 data = HeapAlloc(GetProcessHeap(), 0, file_size.QuadPart);
113 if (data)
114 r = ReadFile(file, data, file_size.QuadPart, &read_size, NULL);
115 CloseHandle(file);
116 if (!r) {
117 FIXME("Read filed\n");
118 HeapFree(GetProcessHeap(), 0, data);
119 return NULL;
122 if (read_size > 2 && data[0] == 0xff && data[1] == 0xfe) { /* UTF-16 BOM */
123 ret = SysAllocStringLen((const WCHAR *)(data + 2), (read_size - 2) / sizeof(WCHAR));
124 }else {
125 size = MultiByteToWideChar(CP_ACP, 0, (const char *)data, read_size, NULL, 0);
126 ret = SysAllocStringLen(NULL, size);
127 if (ret)
128 MultiByteToWideChar(CP_ACP, 0, (const char *)data, read_size, ret, size);
130 HeapFree(GetProcessHeap(), 0, data);
132 return ret;
135 static int change_command(int argc, WCHAR *argv[])
137 BOOL have_option = FALSE, enable = FALSE;
138 const WCHAR *task_name = NULL;
139 IRegisteredTask *task;
140 HRESULT hres;
142 while (argc) {
143 if(!wcsicmp(argv[0], tn_optW)) {
144 if (argc < 2) {
145 FIXME("Missing /tn value\n");
146 return 1;
149 if (task_name) {
150 FIXME("Duplicated /tn argument\n");
151 return 1;
154 task_name = argv[1];
155 argc -= 2;
156 argv += 2;
157 }else if (!wcsicmp(argv[0], enable_optW)) {
158 enable = TRUE;
159 have_option = TRUE;
160 argc--;
161 argv++;
162 }else if (!wcsicmp(argv[0], tr_optW)) {
163 if (argc < 2) {
164 FIXME("Missing /tr value\n");
165 return 1;
168 FIXME("Unsupported /tr option %s\n", debugstr_w(argv[1]));
169 have_option = TRUE;
170 argc -= 2;
171 argv += 2;
172 }else {
173 FIXME("Unsupported arguments %s\n", debugstr_w(argv[0]));
174 return 1;
178 if (!task_name) {
179 FIXME("Missing /tn option\n");
180 return 1;
183 if (!have_option) {
184 FIXME("Missing change options\n");
185 return 1;
188 task = get_registered_task(task_name);
189 if (!task)
190 return 1;
192 if (enable) {
193 hres = IRegisteredTask_put_Enabled(task, VARIANT_TRUE);
194 if (FAILED(hres)) {
195 IRegisteredTask_Release(task);
196 FIXME("put_Enabled failed: %08x\n", hres);
197 return 1;
201 IRegisteredTask_Release(task);
202 return 0;
205 static int create_command(int argc, WCHAR *argv[])
207 const WCHAR *task_name = NULL, *xml_file = NULL;
208 ITaskFolder *root = NULL;
209 LONG flags = TASK_CREATE;
210 IRegisteredTask *task;
211 VARIANT empty;
212 BSTR str, xml;
213 HRESULT hres;
215 while (argc) {
216 if (!wcsicmp(argv[0], xml_optW)) {
217 if (argc < 2) {
218 FIXME("Missing /xml value\n");
219 return 1;
222 if (xml_file) {
223 FIXME("Duplicated /xml argument\n");
224 return 1;
227 xml_file = argv[1];
228 argc -= 2;
229 argv += 2;
230 }else if(!wcsicmp(argv[0], tn_optW)) {
231 if (argc < 2) {
232 FIXME("Missing /tn value\n");
233 return 1;
236 if (task_name) {
237 FIXME("Duplicated /tn argument\n");
238 return 1;
241 task_name = argv[1];
242 argc -= 2;
243 argv += 2;
244 }else if(!wcsicmp(argv[0], f_optW)) {
245 flags = TASK_CREATE_OR_UPDATE;
246 argc--;
247 argv++;
248 }else if (!wcsicmp(argv[0], ru_optW)) {
249 if (argc < 2) {
250 FIXME("Missing /ru value\n");
251 return 1;
254 FIXME("Unsupported /ru option %s\n", debugstr_w(argv[1]));
255 argc -= 2;
256 argv += 2;
257 }else {
258 FIXME("Unsupported argument %s\n", debugstr_w(argv[0]));
259 return 1;
263 if (!task_name) {
264 FIXME("Missing /tn argument\n");
265 return 1;
268 if (!xml_file) {
269 FIXME("Missing /xml argument\n");
270 return E_FAIL;
273 xml = read_file_to_bstr(xml_file);
274 if (!xml)
275 return 1;
277 root = get_tasks_root_folder();
278 if (!root) {
279 SysFreeString(xml);
280 return 1;
283 V_VT(&empty) = VT_EMPTY;
284 str = SysAllocString(task_name);
285 hres = ITaskFolder_RegisterTask(root, str, xml, flags, empty, empty,
286 TASK_LOGON_NONE, empty, &task);
287 SysFreeString(str);
288 SysFreeString(xml);
289 ITaskFolder_Release(root);
290 if (FAILED(hres))
291 return 1;
293 IRegisteredTask_Release(task);
294 return 0;
297 static int delete_command(int argc, WCHAR *argv[])
299 const WCHAR *task_name = NULL;
300 ITaskFolder *root = NULL;
301 BSTR str;
302 HRESULT hres;
304 while (argc) {
305 if (!wcsicmp(argv[0], f_optW)) {
306 TRACE("force opt\n");
307 argc--;
308 argv++;
309 }else if(!wcsicmp(argv[0], tn_optW)) {
310 if (argc < 2) {
311 FIXME("Missing /tn value\n");
312 return 1;
315 if (task_name) {
316 FIXME("Duplicated /tn argument\n");
317 return 1;
320 task_name = argv[1];
321 argc -= 2;
322 argv += 2;
323 }else {
324 FIXME("Unsupported argument %s\n", debugstr_w(argv[0]));
325 return 1;
329 if (!task_name) {
330 FIXME("Missing /tn argument\n");
331 return 1;
334 root = get_tasks_root_folder();
335 if (!root)
336 return 1;
338 str = SysAllocString(task_name);
339 hres = ITaskFolder_DeleteTask(root, str, 0);
340 SysFreeString(str);
341 ITaskFolder_Release(root);
342 if (FAILED(hres))
343 return 1;
345 return 0;
348 int wmain(int argc, WCHAR *argv[])
350 int i, ret = 0;
352 for (i = 0; i < argc; i++)
353 TRACE(" %s", wine_dbgstr_w(argv[i]));
354 TRACE("\n");
356 CoInitialize(NULL);
358 if (argc < 2)
359 FIXME("Print current tasks state\n");
360 else if (!wcsicmp(argv[1], change_optW))
361 ret = change_command(argc - 2, argv + 2);
362 else if (!wcsicmp(argv[1], create_optW))
363 ret = create_command(argc - 2, argv + 2);
364 else if (!wcsicmp(argv[1], delete_optW))
365 ret = delete_command(argc - 2, argv + 2);
366 else
367 FIXME("Unsupported command %s\n", debugstr_w(argv[1]));
369 CoUninitialize();
370 return ret;