ReactOS  0.4.12-dev-14-gd0c8636
schtasks.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Detlef Riekenberg
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #define COBJMACROS
20 
21 #include "initguid.h"
22 #include "taskschd.h"
23 
24 #include "wine/debug.h"
25 #include "wine/unicode.h"
26 
28 
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};
38 
39 static ITaskFolder *get_tasks_root_folder(void)
40 {
41  ITaskService *service;
42  ITaskFolder *root;
43  VARIANT empty;
44  HRESULT hres;
45 
46  hres = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER,
47  &IID_ITaskService, (void**)&service);
48  if (FAILED(hres))
49  return NULL;
50 
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;
56  }
57 
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;
63  }
64 
65  return root;
66 }
67 
68 static IRegisteredTask *get_registered_task(const WCHAR *name)
69 {
70  IRegisteredTask *registered_task;
71  ITaskFolder *root;
72  BSTR str;
73  HRESULT hres;
74 
75  root = get_tasks_root_folder();
76  if (!root)
77  return NULL;
78 
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;
86  }
87 
88  return registered_task;
89 }
90 
92 {
94  DWORD read_size, size;
95  unsigned char *data;
96  HANDLE file;
97  BOOL r = FALSE;
98  BSTR ret;
99 
100  file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
102  if (file == INVALID_HANDLE_VALUE) {
103  FIXME("Could not open file\n");
104  return NULL;
105  }
106 
107  if (!GetFileSizeEx(file, &file_size) || !file_size.QuadPart) {
108  FIXME("Empty file\n");
109  CloseHandle(file);
110  return NULL;
111  }
112 
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;
121  }
122 
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);
130  }
131  HeapFree(GetProcessHeap(), 0, data);
132 
133  return ret;
134 }
135 
136 static int change_command(int argc, WCHAR *argv[])
137 {
138  BOOL have_option = FALSE, enable = FALSE;
139  const WCHAR *task_name = NULL;
140  IRegisteredTask *task;
141  HRESULT hres;
142 
143  while (argc) {
144  if(!strcmpiW(argv[0], tn_optW)) {
145  if (argc < 2) {
146  FIXME("Missing /tn value\n");
147  return 1;
148  }
149 
150  if (task_name) {
151  FIXME("Duplicated /tn argument\n");
152  return 1;
153  }
154 
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;
167  }
168 
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;
176  }
177  }
178 
179  if (!task_name) {
180  FIXME("Missing /tn option\n");
181  return 1;
182  }
183 
184  if (!have_option) {
185  FIXME("Missing change options\n");
186  return 1;
187  }
188 
189  task = get_registered_task(task_name);
190  if (!task)
191  return 1;
192 
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;
199  }
200  }
201 
202  IRegisteredTask_Release(task);
203  return 0;
204 }
205 
206 static int create_command(int argc, WCHAR *argv[])
207 {
208  const WCHAR *task_name = NULL, *xml_file = NULL;
209  ITaskFolder *root = NULL;
211  IRegisteredTask *task;
212  VARIANT empty;
213  BSTR str, xml;
214  HRESULT hres;
215 
216  while (argc) {
217  if (!strcmpiW(argv[0], xml_optW)) {
218  if (argc < 2) {
219  FIXME("Missing /xml value\n");
220  return 1;
221  }
222 
223  if (xml_file) {
224  FIXME("Duplicated /xml argument\n");
225  return 1;
226  }
227 
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;
235  }
236 
237  if (task_name) {
238  FIXME("Duplicated /tn argument\n");
239  return 1;
240  }
241 
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;
253  }
254 
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;
261  }
262  }
263 
264  if (!task_name) {
265  FIXME("Missing /tn argument\n");
266  return 1;
267  }
268 
269  if (!xml_file) {
270  FIXME("Missing /xml argument\n");
271  return E_FAIL;
272  }
273 
274  xml = read_file_to_bstr(xml_file);
275  if (!xml)
276  return 1;
277 
278  root = get_tasks_root_folder();
279  if (!root) {
280  SysFreeString(xml);
281  return 1;
282  }
283 
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;
293 
294  IRegisteredTask_Release(task);
295  return 0;
296 }
297 
298 static int delete_command(int argc, WCHAR *argv[])
299 {
300  const WCHAR *task_name = NULL;
301  ITaskFolder *root = NULL;
302  BSTR str;
303  HRESULT hres;
304 
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;
314  }
315 
316  if (task_name) {
317  FIXME("Duplicated /tn argument\n");
318  return 1;
319  }
320 
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;
327  }
328  }
329 
330  if (!task_name) {
331  FIXME("Missing /tn argument\n");
332  return 1;
333  }
334 
335  root = get_tasks_root_folder();
336  if (!root)
337  return 1;
338 
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;
345 
346  return 0;
347 }
348 
349 int wmain(int argc, WCHAR *argv[])
350 {
351  int i, ret = 0;
352 
353  for (i = 0; i < argc; i++)
354  TRACE(" %s", wine_dbgstr_w(argv[i]));
355  TRACE("\n");
356 
358 
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]));
369 
370  CoUninitialize();
371  return ret;
372 }
static const WCHAR ru_optW[]
Definition: schtasks.c:34
static int argc
Definition: ServiceArgs.c:12
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:343
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define CP_ACP
Definition: compat.h:99
struct _root root
void WINAPI SysFreeString(BSTR str)
Definition: oleaut.c:275
static const WCHAR enable_optW[]
Definition: schtasks.c:32
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
static const WCHAR xml_optW[]
Definition: schtasks.c:37
int wmain(int argc, WCHAR *argv[])
Definition: schtasks.c:349
OLECHAR * BSTR
Definition: compat.h:1927
#define E_FAIL
Definition: ddrawi.h:102
static char ** argv
Definition: ServiceArgs.c:11
#define FILE_SHARE_READ
Definition: compat.h:125
static const WCHAR empty[]
Definition: task.c:29
GLenum GLclampf GLint i
Definition: glfuncs.h:14
long LONG
Definition: pedump.c:60
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:242
static const WCHAR change_optW[]
Definition: schtasks.c:29
static const WCHAR tr_optW[]
Definition: schtasks.c:36
#define OPEN_EXISTING
Definition: compat.h:426
static ITaskFolder * get_tasks_root_folder(void)
Definition: schtasks.c:39
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
WINE_DEFAULT_DEBUG_CHANNEL(schtasks)
LONG HRESULT
Definition: typedefs.h:77
const char file[]
Definition: icontest.c:11
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
#define GetFileSizeEx
Definition: compat.h:414
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define V_VT(A)
Definition: oleauto.h:211
static int delete_command(int argc, WCHAR *argv[])
Definition: schtasks.c:298
#define GENERIC_READ
Definition: compat.h:124
static const WCHAR create_optW[]
Definition: schtasks.c:30
#define strcmpiW(s1, s2)
Definition: unicode.h:39
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3237
static const WCHAR f_optW[]
Definition: schtasks.c:33
GLboolean enable
Definition: glext.h:11120
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1994
static IRegisteredTask * get_registered_task(const WCHAR *name)
Definition: schtasks.c:68
#define MultiByteToWideChar
Definition: compat.h:100
static LPCWSTR file_name
Definition: protocol.c:146
#define CreateFileW
Definition: compat.h:400
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1900
Definition: name.c:36
static int change_command(int argc, WCHAR *argv[])
Definition: schtasks.c:136
static const WCHAR delete_optW[]
Definition: schtasks.c:31
static BSTR read_file_to_bstr(const WCHAR *file_name)
Definition: schtasks.c:91
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define HeapFree(x, y, z)
Definition: compat.h:394
static const WCHAR tn_optW[]
Definition: schtasks.c:35
#define file_size(inode)
Definition: reiserfs_fs.h:1869
LONGLONG QuadPart
Definition: typedefs.h:112
static int create_command(int argc, WCHAR *argv[])
Definition: schtasks.c:206