user32/tests: Make test_LoadImage_working_directory_run() static.
[wine.git] / programs / schtasks / schtasks.c
blob2ac7544cd02e171ae541abbe9cb7e8b83d0ad439
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"
25 #include "wine/unicode.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(schtasks);
29 static const WCHAR change_optW[] = {'/','c','h','a','n','g','e',0};
30 static const WCHAR create_optW[] = {'/','c','r','e','a','t','e',0};
31 static const WCHAR delete_optW[] = {'/','d','e','l','e','t','e',0};
32 static const WCHAR enable_optW[] = {'/','e','n','a','b','l','e',0};
33 static const WCHAR f_optW[] = {'/','f',0};
34 static const WCHAR ru_optW[] = {'/','r','u',0};
35 static const WCHAR tn_optW[] = {'/','t','n',0};
36 static const WCHAR tr_optW[] = {'/','t','r',0};
37 static const WCHAR xml_optW[] = {'/','x','m','l',0};
39 static ITaskFolder *get_tasks_root_folder(void)
41 ITaskService *service;
42 ITaskFolder *root;
43 VARIANT empty;
44 HRESULT hres;
46 hres = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER,
47 &IID_ITaskService, (void**)&service);
48 if (FAILED(hres))
49 return NULL;
51 V_VT(&empty) = VT_EMPTY;
52 hres = ITaskService_Connect(service, empty, empty, empty, empty);
53 if (FAILED(hres)) {
54 FIXME("Connect failed: %08x\n", hres);
55 return NULL;
58 hres = ITaskService_GetFolder(service, NULL, &root);
59 ITaskService_Release(service);
60 if (FAILED(hres)) {
61 FIXME("GetFolder failed: %08x\n", hres);
62 return NULL;
65 return root;
68 static IRegisteredTask *get_registered_task(const WCHAR *name)
70 IRegisteredTask *registered_task;
71 ITaskFolder *root;
72 BSTR str;
73 HRESULT hres;
75 root = get_tasks_root_folder();
76 if (!root)
77 return NULL;
79 str = SysAllocString(name);
80 hres = ITaskFolder_GetTask(root, str, &registered_task);
81 SysFreeString(str);
82 ITaskFolder_Release(root);
83 if (FAILED(hres)) {
84 FIXME("GetTask failed: %08x\n", hres);
85 return NULL;
88 return registered_task;
91 static BSTR read_file_to_bstr(const WCHAR *file_name)
93 LARGE_INTEGER file_size;
94 DWORD read_size, size;
95 unsigned char *data;
96 HANDLE file;
97 BOOL r = FALSE;
98 BSTR ret;
100 file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
101 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
102 if (file == INVALID_HANDLE_VALUE) {
103 FIXME("Could not open file\n");
104 return NULL;
107 if (!GetFileSizeEx(file, &file_size) || !file_size.QuadPart) {
108 FIXME("Empty file\n");
109 CloseHandle(file);
110 return NULL;
113 data = HeapAlloc(GetProcessHeap(), 0, file_size.QuadPart);
114 if (data)
115 r = ReadFile(file, data, file_size.QuadPart, &read_size, NULL);
116 CloseHandle(file);
117 if (!r) {
118 FIXME("Read filed\n");
119 HeapFree(GetProcessHeap(), 0, data);
120 return NULL;
123 if (read_size > 2 && data[0] == 0xff && data[1] == 0xfe) { /* UTF-16 BOM */
124 ret = SysAllocStringLen((const WCHAR *)(data + 2), (read_size - 2) / sizeof(WCHAR));
125 }else {
126 size = MultiByteToWideChar(CP_ACP, 0, (const char *)data, read_size, NULL, 0);
127 ret = SysAllocStringLen(NULL, size);
128 if (ret)
129 MultiByteToWideChar(CP_ACP, 0, (const char *)data, read_size, ret, size);
131 HeapFree(GetProcessHeap(), 0, data);
133 return ret;
136 static int change_command(int argc, WCHAR *argv[])
138 BOOL have_option = FALSE, enable = FALSE;
139 const WCHAR *task_name = NULL;
140 IRegisteredTask *task;
141 HRESULT hres;
143 while (argc) {
144 if(!strcmpiW(argv[0], tn_optW)) {
145 if (argc < 2) {
146 FIXME("Missing /tn value\n");
147 return 1;
150 if (task_name) {
151 FIXME("Duplicated /tn argument\n");
152 return 1;
155 task_name = argv[1];
156 argc -= 2;
157 argv += 2;
158 }else if (!strcmpiW(argv[0], enable_optW)) {
159 enable = TRUE;
160 have_option = TRUE;
161 argc--;
162 argv++;
163 }else if (!strcmpiW(argv[0], tr_optW)) {
164 if (argc < 2) {
165 FIXME("Missing /tr value\n");
166 return 1;
169 FIXME("Unsupported /tr option %s\n", debugstr_w(argv[1]));
170 have_option = TRUE;
171 argc -= 2;
172 argv += 2;
173 }else {
174 FIXME("Unsupported arguments %s\n", debugstr_w(argv[0]));
175 return 1;
179 if (!task_name) {
180 FIXME("Missing /tn option\n");
181 return 1;
184 if (!have_option) {
185 FIXME("Missing change options\n");
186 return 1;
189 task = get_registered_task(task_name);
190 if (!task)
191 return 1;
193 if (enable) {
194 hres = IRegisteredTask_put_Enabled(task, VARIANT_TRUE);
195 if (FAILED(hres)) {
196 IRegisteredTask_Release(task);
197 FIXME("put_Enabled failed: %08x\n", hres);
198 return 1;
202 IRegisteredTask_Release(task);
203 return 0;
206 static int create_command(int argc, WCHAR *argv[])
208 const WCHAR *task_name = NULL, *xml_file = NULL;
209 ITaskFolder *root = NULL;
210 LONG flags = TASK_CREATE;
211 IRegisteredTask *task;
212 VARIANT empty;
213 BSTR str, xml;
214 HRESULT hres;
216 while (argc) {
217 if (!strcmpiW(argv[0], xml_optW)) {
218 if (argc < 2) {
219 FIXME("Missing /xml value\n");
220 return 1;
223 if (xml_file) {
224 FIXME("Duplicated /xml argument\n");
225 return 1;
228 xml_file = argv[1];
229 argc -= 2;
230 argv += 2;
231 }else if(!strcmpiW(argv[0], tn_optW)) {
232 if (argc < 2) {
233 FIXME("Missing /tn value\n");
234 return 1;
237 if (task_name) {
238 FIXME("Duplicated /tn argument\n");
239 return 1;
242 task_name = argv[1];
243 argc -= 2;
244 argv += 2;
245 }else if(!strcmpiW(argv[0], f_optW)) {
246 flags = TASK_CREATE_OR_UPDATE;
247 argc--;
248 argv++;
249 }else if (!strcmpiW(argv[0], ru_optW)) {
250 if (argc < 2) {
251 FIXME("Missing /ru value\n");
252 return 1;
255 FIXME("Unsupported /ru option %s\n", debugstr_w(argv[1]));
256 argc -= 2;
257 argv += 2;
258 }else {
259 FIXME("Unsupported argument %s\n", debugstr_w(argv[0]));
260 return 1;
264 if (!task_name) {
265 FIXME("Missing /tn argument\n");
266 return 1;
269 if (!xml_file) {
270 FIXME("Missing /xml argument\n");
271 return E_FAIL;
274 xml = read_file_to_bstr(xml_file);
275 if (!xml)
276 return 1;
278 root = get_tasks_root_folder();
279 if (!root) {
280 SysFreeString(xml);
281 return 1;
284 V_VT(&empty) = VT_EMPTY;
285 str = SysAllocString(task_name);
286 hres = ITaskFolder_RegisterTask(root, str, xml, flags, empty, empty,
287 TASK_LOGON_NONE, empty, &task);
288 SysFreeString(str);
289 SysFreeString(xml);
290 ITaskFolder_Release(root);
291 if (FAILED(hres))
292 return 1;
294 IRegisteredTask_Release(task);
295 return 0;
298 static int delete_command(int argc, WCHAR *argv[])
300 const WCHAR *task_name = NULL;
301 ITaskFolder *root = NULL;
302 BSTR str;
303 HRESULT hres;
305 while (argc) {
306 if (!strcmpiW(argv[0], f_optW)) {
307 TRACE("force opt\n");
308 argc--;
309 argv++;
310 }else if(!strcmpiW(argv[0], tn_optW)) {
311 if (argc < 2) {
312 FIXME("Missing /tn value\n");
313 return 1;
316 if (task_name) {
317 FIXME("Duplicated /tn argument\n");
318 return 1;
321 task_name = argv[1];
322 argc -= 2;
323 argv += 2;
324 }else {
325 FIXME("Unsupported argument %s\n", debugstr_w(argv[0]));
326 return 1;
330 if (!task_name) {
331 FIXME("Missing /tn argument\n");
332 return 1;
335 root = get_tasks_root_folder();
336 if (!root)
337 return 1;
339 str = SysAllocString(task_name);
340 hres = ITaskFolder_DeleteTask(root, str, 0);
341 SysFreeString(str);
342 ITaskFolder_Release(root);
343 if (FAILED(hres))
344 return 1;
346 return 0;
349 int wmain(int argc, WCHAR *argv[])
351 int i, ret = 0;
353 for (i = 0; i < argc; i++)
354 TRACE(" %s", wine_dbgstr_w(argv[i]));
355 TRACE("\n");
357 CoInitialize(NULL);
359 if (argc < 2)
360 FIXME("Print current tasks state\n");
361 else if (!strcmpiW(argv[1], change_optW))
362 ret = change_command(argc - 2, argv + 2);
363 else if (!strcmpiW(argv[1], create_optW))
364 ret = create_command(argc - 2, argv + 2);
365 else if (!strcmpiW(argv[1], delete_optW))
366 ret = delete_command(argc - 2, argv + 2);
367 else
368 FIXME("Unsupported command %s\n", debugstr_w(argv[1]));
370 CoUninitialize();
371 return ret;