Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47152
This is initial part which ignores the options.
-- v20: schtasks: Stub implementation of /sc option in create command. schtasks: Ignore /tr /sc /rl options in create command. schtasks: Fix return codes and add new tests.
From: Vijay Kiran Kamuju infyquest@gmail.com
--- programs/schtasks/schtasks.c | 220 ++++++++++++----------------- programs/schtasks/tests/schtasks.c | 88 +++++++----- 2 files changed, 141 insertions(+), 167 deletions(-)
diff --git a/programs/schtasks/schtasks.c b/programs/schtasks/schtasks.c index c9434801db8..1c6350f925b 100644 --- a/programs/schtasks/schtasks.c +++ b/programs/schtasks/schtasks.c @@ -25,6 +25,16 @@
WINE_DEFAULT_DEBUG_CHANNEL(schtasks);
+typedef struct _hash_args { + WCHAR option[7]; + BOOL is_supported; + BOOL is_single; + union { + BOOL enable; + WCHAR *value; + }; +} hash_args; + static ITaskFolder *get_tasks_root_folder(void) { ITaskService *service; @@ -111,7 +121,7 @@ static BSTR read_file_to_bstr(const WCHAR *file_name)
if (read_size > 2 && data[0] == 0xff && data[1] == 0xfe) { /* UTF-16 BOM */ ret = SysAllocStringLen((const WCHAR *)(data + 2), (read_size - 2) / sizeof(WCHAR)); - }else { + } else { size = MultiByteToWideChar(CP_ACP, 0, (const char *)data, read_size, NULL, 0); ret = SysAllocStringLen(NULL, size); if (ret) @@ -122,64 +132,76 @@ static BSTR read_file_to_bstr(const WCHAR *file_name) return ret; }
-static int change_command(int argc, WCHAR *argv[]) +static BOOL search_option(WCHAR *option, hash_args inputs[], int icount) { - BOOL have_option = FALSE, enable = FALSE; - const WCHAR *task_name = NULL; - IRegisteredTask *task; - HRESULT hres; + int i; + for (i = 0; i < icount; i++) { + if (!wcsicmp(option, inputs[i].option)) + return i; + } + return -1; +} + +static BOOL check_args(int argc, WCHAR *argv[], hash_args inputs[], int icount) +{ + int index;
while (argc) { - if (!wcsicmp(argv[0], L"/tn")) { - if (argc < 2) { - FIXME("Missing /tn value\n"); - return 1; - } - - if (task_name) { - FIXME("Duplicated /tn argument\n"); - return 1; - } - - task_name = argv[1]; - argc -= 2; - argv += 2; - } else if (!wcsicmp(argv[0], L"/enable")) { - enable = TRUE; - have_option = TRUE; - argc--; - argv++; - } else if (!wcsicmp(argv[0], L"/tr")) { - if (argc < 2) { - FIXME("Missing /tr value\n"); - return 1; - } - - FIXME("Unsupported /tr option %s\n", debugstr_w(argv[1])); - have_option = TRUE; - argc -= 2; - argv += 2; - }else { - FIXME("Unsupported arguments %s\n", debugstr_w(argv[0])); - return 1; + index = search_option(argv[0], inputs, icount); + if (index != -1) { + if (inputs[index].is_single) { + inputs[index].enable = TRUE; + argc--; + argv++; + } else { + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing %s value\n", debugstr_w(inputs[index].option)); + return FALSE; + } + if (inputs[index].value) { + ERR("Duplicated %s argument\n", debugstr_w(inputs[index].option)); + return FALSE; + } + inputs[index].value = argv[1]; + argc -= 2; + argv += 2; + } + if (!inputs[index].is_supported) + FIXME("Unsupported %s option %s\n", debugstr_w(inputs[index].option),debugstr_w(inputs[index].value)); + } else { + FIXME("Unsupported arguments %s\n", debugstr_w(argv[0])); + return FALSE; } } + return TRUE; +} + +static int change_command(int argc, WCHAR *argv[]) +{ + hash_args change_args[3] = { {L"/tn", TRUE, FALSE}, + {L"/tr", TRUE, FALSE}, + {L"/enable", TRUE, TRUE} }; + IRegisteredTask *task; + HRESULT hres; + + if (!check_args(argc, argv, change_args, 3 )) + return 1;
- if (!task_name) { - FIXME("Missing /tn option\n"); + if (!change_args[0].value) { + ERR("Missing /tn option\n"); return 1; }
- if (!have_option) { - FIXME("Missing change options\n"); + if (!change_args[2].enable && !change_args[1].value) { + ERR("Missing change options\n"); return 1; }
- task = get_registered_task(task_name); + task = get_registered_task(change_args[0].value); if (!task) return 1;
- if (enable) { + if (change_args[2].enable) { hres = IRegisteredTask_put_Enabled(task, VARIANT_TRUE); if (FAILED(hres)) { IRegisteredTask_Release(task); @@ -194,7 +216,10 @@ static int change_command(int argc, WCHAR *argv[])
static int create_command(int argc, WCHAR *argv[]) { - const WCHAR *task_name = NULL, *xml_file = NULL; + hash_args create_args[4] = { {L"/tn", TRUE, FALSE}, + {L"/xml", TRUE, FALSE}, + {L"/f", TRUE, TRUE}, + {L"/ru", FALSE, FALSE} }; ITaskFolder *root = NULL; LONG flags = TASK_CREATE; IRegisteredTask *task; @@ -202,67 +227,24 @@ static int create_command(int argc, WCHAR *argv[]) BSTR str, xml; HRESULT hres;
- while (argc) { - if (!wcsicmp(argv[0], L"/xml")) { - if (argc < 2) { - FIXME("Missing /xml value\n"); - return 1; - } - - if (xml_file) { - FIXME("Duplicated /xml argument\n"); - return 1; - } - - xml_file = argv[1]; - argc -= 2; - argv += 2; - } else if (!wcsicmp(argv[0], L"/tn")) { - if (argc < 2) { - FIXME("Missing /tn value\n"); - return 1; - } - - if (task_name) { - FIXME("Duplicated /tn argument\n"); - return 1; - } - - task_name = argv[1]; - argc -= 2; - argv += 2; - } else if (!wcsicmp(argv[0], L"/f")) { - flags = TASK_CREATE_OR_UPDATE; - argc--; - argv++; - } else if (!wcsicmp(argv[0], L"/ru")) { - if (argc < 2) { - FIXME("Missing /ru value\n"); - return 1; - } - - FIXME("Unsupported /ru option %s\n", debugstr_w(argv[1])); - argc -= 2; - argv += 2; - }else { - FIXME("Unsupported argument %s\n", debugstr_w(argv[0])); - return 1; - } - } + if (!check_args(argc, argv, create_args, 4 )) + return E_FAIL;
- if (!task_name) { - FIXME("Missing /tn argument\n"); - return 1; + if (!create_args[0].value) { + ERR("Missing /tn argument\n"); + return E_FAIL; }
- if (!xml_file) { - FIXME("Missing /xml argument\n"); + if (!create_args[1].value) { + ERR("Missing /xml argument\n"); return E_FAIL; }
- xml = read_file_to_bstr(xml_file); + if (create_args[2].enable) flags = TASK_CREATE_OR_UPDATE; + + xml = read_file_to_bstr(create_args[1].value); if (!xml) - return 1; + return E_FAIL;
root = get_tasks_root_folder(); if (!root) { @@ -271,7 +253,7 @@ static int create_command(int argc, WCHAR *argv[]) }
V_VT(&empty) = VT_EMPTY; - str = SysAllocString(task_name); + str = SysAllocString(create_args[0].value); hres = ITaskFolder_RegisterTask(root, str, xml, flags, empty, empty, TASK_LOGON_NONE, empty, &task); SysFreeString(str); @@ -286,38 +268,17 @@ static int create_command(int argc, WCHAR *argv[])
static int delete_command(int argc, WCHAR *argv[]) { - const WCHAR *task_name = NULL; + hash_args delete_args[2] = { {L"/tn", TRUE, FALSE}, + {L"/f", TRUE, TRUE} }; ITaskFolder *root = NULL; BSTR str; HRESULT hres;
- while (argc) { - if (!wcsicmp(argv[0], L"/f")) { - TRACE("force opt\n"); - argc--; - argv++; - } else if (!wcsicmp(argv[0], L"/tn")) { - if (argc < 2) { - FIXME("Missing /tn value\n"); - return 1; - } - - if (task_name) { - FIXME("Duplicated /tn argument\n"); - return 1; - } - - task_name = argv[1]; - argc -= 2; - argv += 2; - }else { - FIXME("Unsupported argument %s\n", debugstr_w(argv[0])); - return 1; - } - } + if (!check_args(argc, argv, delete_args, 2 )) + return 1;
- if (!task_name) { - FIXME("Missing /tn argument\n"); + if (!delete_args[0].value) { + ERR("Missing /tn argument\n"); return 1; }
@@ -325,7 +286,7 @@ static int delete_command(int argc, WCHAR *argv[]) if (!root) return 1;
- str = SysAllocString(task_name); + str = SysAllocString(delete_args[0].value); hres = ITaskFolder_DeleteTask(root, str, 0); SysFreeString(str); ITaskFolder_Release(root); @@ -354,7 +315,10 @@ int __cdecl wmain(int argc, WCHAR *argv[]) else if (!wcsicmp(argv[1], L"/delete")) ret = delete_command(argc - 2, argv + 2); else + { FIXME("Unsupported command %s\n", debugstr_w(argv[1])); + ret = 1; + }
CoUninitialize(); return ret; diff --git a/programs/schtasks/tests/schtasks.c b/programs/schtasks/tests/schtasks.c index 3ed2378c90c..8323fe5fd86 100644 --- a/programs/schtasks/tests/schtasks.c +++ b/programs/schtasks/tests/schtasks.c @@ -29,6 +29,11 @@ static ITaskService *service; static ITaskFolder *root;
+typedef struct _schtask_test { + const char *cmd; + DWORD expect; +} schtask_test; + static const char xml_a[] = "<?xml version=\"1.0\"?>\n" "<Task xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task%5C%22%3E%5Cn" @@ -92,8 +97,8 @@ static BOOL check_win_version(int min_major, int min_minor) } #define is_win10_plus() check_win_version(10, 0)
-#define run_command(a) _run_command(__LINE__,a) -static DWORD _run_command(unsigned line, const char *cmd) +#define run_command(a, e) _run_command(__LINE__, a, e) +static BOOL _run_command(unsigned line, const char *cmd, DWORD expected) { STARTUPINFOA si = {sizeof(STARTUPINFOA)}; PROCESS_INFORMATION pi; @@ -106,10 +111,11 @@ static DWORD _run_command(unsigned line, const char *cmd) si.hStdOutput = INVALID_HANDLE_VALUE; si.hStdError = INVALID_HANDLE_VALUE;
- strcpy(command, cmd); + strcpy(command, "schtasks.exe "); + strcat(command, cmd); r = CreateProcessA(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); ok_(__FILE__,line)(r, "CreateProcess failed: %lu\n", GetLastError()); - if(!r) return -1; + if(!r) return FALSE;
ret = WaitForSingleObject(pi.hProcess, 10000); ok_(__FILE__,line)(ret == WAIT_OBJECT_0, "wait failed\n"); @@ -121,7 +127,9 @@ static DWORD _run_command(unsigned line, const char *cmd)
CloseHandle(pi.hThread); CloseHandle(pi.hProcess); - return ret; + + ok_(__FILE__,line)(ret == expected, "Expected %lu, got = %lu\n", expected, ret); + return r; }
#define register_task(a) _register_task(__LINE__,a) @@ -201,8 +209,37 @@ static BOOL initialize_task_service(void) return TRUE; }
+static void run_command_list(schtask_test *cmdlist, int len) +{ + int i; + + for (i = 0; i < len; i++) + { + run_command(cmdlist[i].cmd, cmdlist[i].expect); + } +} + START_TEST(schtasks) { + static schtask_test querylist[] = { { "", 0 }, + { "/wine", 1 } }; + static schtask_test changlist[] = { { "/change /tn winetest /enable", 0 }, + { "/change /tn winetest /tn /enable", 1,} }; + static schtask_test unreglist[] = { { "/change /tn winetest /enable", 1 } }; + static schtask_test creatlist[] = { { "/CHANGE /tn wine\test\winetest /enable", 0 }, + { "/delete /f /tn /tn wine\test\winetest", 1 }, + { "/delete /f /tn wine\test\winetest", 0 }, + { "/Change /tn wine\test\winetest /enable", 1 }, + { "/create /xml test.xml /tn wine\winetest", 0 }, + { "/create /xml test.xml /tn wine\winetest /tn", E_FAIL }, + { "/create /xml test.xml /tn wine\winetest /xml", E_FAIL }, + { "/create /xml test.xml /tn wine\winetest /tn test", E_FAIL }, + { "/create /xml test.xml /tn wine\winetest /xml empty.xml", E_FAIL }, + { "/change /tn wine\winetest /enable", 0 }, + { "/create /xml test.xml /f /tn wine\winetest", 0 }, + { "/create /xml test.xml /tn wine\winetest", 1 }, + { "/Delete /f /tn wine\winetest", 0 }, + { "/create /tn wine\winetest", E_FAIL } }; static WCHAR wineW[] = L"\wine"; static WCHAR wine_testW[] = L"\wine\test"; DWORD r; @@ -219,55 +256,28 @@ START_TEST(schtasks) return; }
- r = run_command("schtasks"); - ok(r == 0, "r = %lu\n", r); + create_file("test.xml", xml_a); + + run_command_list(querylist, ARRAY_SIZE(querylist));
register_task("winetest");
- r = run_command("schtasks /change /tn winetest /enable"); - ok(r == 0, "r = %lu\n", r); + run_command_list(changlist, ARRAY_SIZE(changlist));
unregister_task("winetest");
- r = run_command("schtasks /change /tn winetest /enable"); - ok(r == 1, "r = %lu\n", r); + run_command_list(unreglist, ARRAY_SIZE(unreglist));
register_task("wine\test\winetest");
- r = run_command("schtasks /CHANGE /tn wine\test\winetest /enable"); - ok(r == 0, "r = %lu\n", r); - - r = run_command("schtasks /delete /f /tn wine\test\winetest"); - ok(r == 0, "r = %lu\n", r); - - r = run_command("schtasks /Change /tn wine\test\winetest /enable"); - ok(r == 1, "r = %lu\n", r); - - create_file("test.xml", xml_a); - - r = run_command("schtasks /create /xml test.xml /tn wine\winetest"); - ok(r == 0, "r = %lu\n", r); - - r = run_command("schtasks /change /tn wine\winetest /enable"); - ok(r == 0, "r = %lu\n", r); - - r = run_command("schtasks /create /xml test.xml /f /tn wine\winetest"); - ok(r == 0, "r = %lu\n", r); /* task already exists, but /f argument provided */ - - r = run_command("schtasks /create /xml test.xml /tn wine\winetest"); - ok(r == 1, "r = %lu\n", r); /* task already exists */ - - r = run_command("schtasks /create /tn wine\winetest"); - ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ - - r = run_command("schtasks /Delete /f /tn wine\winetest"); - ok(r == 0, "r = %lu\n", r); + run_command_list(creatlist, ARRAY_SIZE(creatlist));
r = DeleteFileA("test.xml"); ok(r, "DeleteFileA failed: %lu\n", GetLastError());
r = ITaskFolder_DeleteFolder(root, wine_testW, 0); ok(r == S_OK, "DeleteFolder(\wine\test) failed: %lx\n", r); + r = ITaskFolder_DeleteFolder(root, wineW, 0); ok(r == S_OK, "DeleteFolder(\wine) failed: %lx\n", r);
From: Vijay Kiran Kamuju infyquest@gmail.com
--- programs/schtasks/schtasks.c | 78 +++++++++++++++++++----------- programs/schtasks/tests/schtasks.c | 24 +++++++-- 2 files changed, 69 insertions(+), 33 deletions(-)
diff --git a/programs/schtasks/schtasks.c b/programs/schtasks/schtasks.c index 1c6350f925b..7fc94205dac 100644 --- a/programs/schtasks/schtasks.c +++ b/programs/schtasks/schtasks.c @@ -132,7 +132,7 @@ static BSTR read_file_to_bstr(const WCHAR *file_name) return ret; }
-static BOOL search_option(WCHAR *option, hash_args inputs[], int icount) +static int search_option(WCHAR *option, hash_args inputs[], int icount) { int i; for (i = 0; i < icount; i++) { @@ -216,9 +216,12 @@ static int change_command(int argc, WCHAR *argv[])
static int create_command(int argc, WCHAR *argv[]) { - hash_args create_args[4] = { {L"/tn", TRUE, FALSE}, + hash_args create_args[7] = { {L"/tn", TRUE, FALSE}, {L"/xml", TRUE, FALSE}, {L"/f", TRUE, TRUE}, + {L"/tr", FALSE, FALSE}, + {L"/sc", FALSE, FALSE}, + {L"/rl", FALSE, FALSE}, {L"/ru", FALSE, FALSE} }; ITaskFolder *root = NULL; LONG flags = TASK_CREATE; @@ -227,7 +230,7 @@ static int create_command(int argc, WCHAR *argv[]) BSTR str, xml; HRESULT hres;
- if (!check_args(argc, argv, create_args, 4 )) + if (!check_args(argc, argv, create_args, 7 )) return E_FAIL;
if (!create_args[0].value) { @@ -235,35 +238,54 @@ static int create_command(int argc, WCHAR *argv[]) return E_FAIL; }
- if (!create_args[1].value) { - ERR("Missing /xml argument\n"); - return E_FAIL; - } - if (create_args[2].enable) flags = TASK_CREATE_OR_UPDATE;
- xml = read_file_to_bstr(create_args[1].value); - if (!xml) - return E_FAIL; + if (!create_args[3].value && !create_args[4].value) { + if (!create_args[1].value) { + ERR("Missing /xml argument\n"); + return E_FAIL; + } else { + xml = read_file_to_bstr(create_args[1].value); + if (!xml) + return 1; + + root = get_tasks_root_folder(); + if (!root) { + SysFreeString(xml); + return 1; + } + + V_VT(&empty) = VT_EMPTY; + str = SysAllocString(create_args[0].value); + hres = ITaskFolder_RegisterTask(root, str, xml, flags, empty, empty, + TASK_LOGON_NONE, empty, &task); + + SysFreeString(str); + SysFreeString(xml); + ITaskFolder_Release(root); + if (FAILED(hres)) + return 1;
- root = get_tasks_root_folder(); - if (!root) { - SysFreeString(xml); - return 1; + IRegisteredTask_Release(task); + return 0; + } + } else { + if (create_args[1].value) { + ERR("/xml option can only be used with /ru /f /tn\n"); + return E_FAIL; + } + if (!create_args[3].value) { + ERR("Missing /tr argument\n"); + return E_FAIL; + } else { + if (!create_args[4].value) { + ERR("Missing /sc argument\n"); + return E_FAIL; + } + } + return 0; } - - V_VT(&empty) = VT_EMPTY; - str = SysAllocString(create_args[0].value); - hres = ITaskFolder_RegisterTask(root, str, xml, flags, empty, empty, - TASK_LOGON_NONE, empty, &task); - SysFreeString(str); - SysFreeString(xml); - ITaskFolder_Release(root); - if (FAILED(hres)) - return 1; - - IRegisteredTask_Release(task); - return 0; + return E_FAIL; }
static int delete_command(int argc, WCHAR *argv[]) diff --git a/programs/schtasks/tests/schtasks.c b/programs/schtasks/tests/schtasks.c index 8323fe5fd86..35900a641f5 100644 --- a/programs/schtasks/tests/schtasks.c +++ b/programs/schtasks/tests/schtasks.c @@ -32,6 +32,7 @@ static ITaskFolder *root; typedef struct _schtask_test { const char *cmd; DWORD expect; + BOOL todo; } schtask_test;
static const char xml_a[] = @@ -97,8 +98,9 @@ static BOOL check_win_version(int min_major, int min_minor) } #define is_win10_plus() check_win_version(10, 0)
-#define run_command(a, e) _run_command(__LINE__, a, e) -static BOOL _run_command(unsigned line, const char *cmd, DWORD expected) +#define run_command(a, e) _run_command(__LINE__, a, e, FALSE) +#define run_command_todo(a, e) _run_command(__LINE__, a, e, TRUE) +static BOOL _run_command(unsigned line, const char *cmd, DWORD expected, BOOL todo) { STARTUPINFOA si = {sizeof(STARTUPINFOA)}; PROCESS_INFORMATION pi; @@ -128,7 +130,10 @@ static BOOL _run_command(unsigned line, const char *cmd, DWORD expected) CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
- ok_(__FILE__,line)(ret == expected, "Expected %lu, got = %lu\n", expected, ret); + if (todo) + todo_wine ok_(__FILE__,line)(ret == expected, "Expected %lu, got = %lu\n", expected, ret); + else + ok_(__FILE__,line)(ret == expected, "Expected %lu, got = %lu\n", expected, ret); return r; }
@@ -215,7 +220,10 @@ static void run_command_list(schtask_test *cmdlist, int len)
for (i = 0; i < len; i++) { - run_command(cmdlist[i].cmd, cmdlist[i].expect); + if (cmdlist[i].todo) + run_command_todo(cmdlist[i].cmd, cmdlist[i].expect); + else + run_command(cmdlist[i].cmd, cmdlist[i].expect); } }
@@ -235,11 +243,17 @@ START_TEST(schtasks) { "/create /xml test.xml /tn wine\winetest /xml", E_FAIL }, { "/create /xml test.xml /tn wine\winetest /tn test", E_FAIL }, { "/create /xml test.xml /tn wine\winetest /xml empty.xml", E_FAIL }, + { "/create /xml test.xml /tn wine\winetest /tr c:\windows\hh.exe", E_FAIL }, { "/change /tn wine\winetest /enable", 0 }, { "/create /xml test.xml /f /tn wine\winetest", 0 }, { "/create /xml test.xml /tn wine\winetest", 1 }, + { "/create /xml test.xml /f /tn wine\winetest /tr c:\windows\hh.exe", E_FAIL }, { "/Delete /f /tn wine\winetest", 0 }, - { "/create /tn wine\winetest", E_FAIL } }; + { "/create /tn wine\winetest", E_FAIL }, + { "/create /tn wine\winetest /tr c:\windows\hh.exe", E_FAIL, FALSE }, + { "/create /tn wine\winetest /tr c:\windows\hh.exe /sc wine", E_FAIL, TRUE }, + { "/create /tn wine\winetest /tr c:\windows\hh.exe /sc daily", 0 }, + { "/DELETE /f /tn wine\winetest", 0, TRUE } }; static WCHAR wineW[] = L"\wine"; static WCHAR wine_testW[] = L"\wine\test"; DWORD r;
From: Vijay Kiran Kamuju infyquest@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47152 --- programs/schtasks/schtasks.c | 33 +++++++++++++++++++++++++++--- programs/schtasks/tests/schtasks.c | 17 ++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/programs/schtasks/schtasks.c b/programs/schtasks/schtasks.c index 7fc94205dac..3cecb9f8953 100644 --- a/programs/schtasks/schtasks.c +++ b/programs/schtasks/schtasks.c @@ -132,16 +132,32 @@ static BSTR read_file_to_bstr(const WCHAR *file_name) return ret; }
-static int search_option(WCHAR *option, hash_args inputs[], int icount) +static int search_str(WCHAR *option, const WCHAR **strlist, int count) { int i; - for (i = 0; i < icount; i++) { - if (!wcsicmp(option, inputs[i].option)) + + for (i = 0; i < count; i++) { + if (!wcsicmp(option, strlist[i])) return i; } + return -1; }
+static int search_option(WCHAR *option, hash_args inputs[], int icount) +{ + int i, ret; + const WCHAR **optlist; + + optlist = malloc(icount * sizeof(WCHAR *)); + for (i = 0; i < icount; i++) + optlist[i] = wcsdup(inputs[i].option); + ret = search_str(option, optlist, icount); + free(optlist); + + return ret; +} + static BOOL check_args(int argc, WCHAR *argv[], hash_args inputs[], int icount) { int index; @@ -216,6 +232,10 @@ static int change_command(int argc, WCHAR *argv[])
static int create_command(int argc, WCHAR *argv[]) { + static const WCHAR *sc_values[] = { L"minute", L"hourly", L"daily", + L"weekly", L"monthly", L"once", + L"onstart", L"onlogon", L"onidle", + L"onevent" }; hash_args create_args[7] = { {L"/tn", TRUE, FALSE}, {L"/xml", TRUE, FALSE}, {L"/f", TRUE, TRUE}, @@ -274,6 +294,7 @@ static int create_command(int argc, WCHAR *argv[]) ERR("/xml option can only be used with /ru /f /tn\n"); return E_FAIL; } + if (!create_args[3].value) { ERR("Missing /tr argument\n"); return E_FAIL; @@ -282,9 +303,15 @@ static int create_command(int argc, WCHAR *argv[]) ERR("Missing /sc argument\n"); return E_FAIL; } + + if (search_str(create_args[4].value, sc_values, 10) == -1) { + ERR("Invalid schedule type %s\n", debugstr_w(create_args[4].value)); + return E_FAIL; + } } return 0; } + return E_FAIL; }
diff --git a/programs/schtasks/tests/schtasks.c b/programs/schtasks/tests/schtasks.c index 35900a641f5..6f7203f21c2 100644 --- a/programs/schtasks/tests/schtasks.c +++ b/programs/schtasks/tests/schtasks.c @@ -238,7 +238,12 @@ START_TEST(schtasks) { "/delete /f /tn /tn wine\test\winetest", 1 }, { "/delete /f /tn wine\test\winetest", 0 }, { "/Change /tn wine\test\winetest /enable", 1 }, - { "/create /xml test.xml /tn wine\winetest", 0 }, + { "/create /xml test.xml", E_FAIL }, + { "/create /xml test.xml /tn", E_FAIL }, + { "/create /xml /tn wine\winetest", E_FAIL }, + { "/create /xml noexist.xml /tn wine\winetest", 1 }, + { "/create /xml empty.xml /tn wine\winetest", 1 }, + { "/create /xml test.xml /tn wine\winetest", 0 }, { "/create /xml test.xml /tn wine\winetest /tn", E_FAIL }, { "/create /xml test.xml /tn wine\winetest /xml", E_FAIL }, { "/create /xml test.xml /tn wine\winetest /tn test", E_FAIL }, @@ -249,9 +254,10 @@ START_TEST(schtasks) { "/create /xml test.xml /tn wine\winetest", 1 }, { "/create /xml test.xml /f /tn wine\winetest /tr c:\windows\hh.exe", E_FAIL }, { "/Delete /f /tn wine\winetest", 0 }, + { "/create /tn", E_FAIL }, { "/create /tn wine\winetest", E_FAIL }, - { "/create /tn wine\winetest /tr c:\windows\hh.exe", E_FAIL, FALSE }, - { "/create /tn wine\winetest /tr c:\windows\hh.exe /sc wine", E_FAIL, TRUE }, + { "/create /tn wine\winetest /tr c:\windows\hh.exe", E_FAIL }, + { "/create /tn wine\winetest /tr c:\windows\hh.exe /sc wine", E_FAIL }, { "/create /tn wine\winetest /tr c:\windows\hh.exe /sc daily", 0 }, { "/DELETE /f /tn wine\winetest", 0, TRUE } }; static WCHAR wineW[] = L"\wine"; @@ -272,6 +278,8 @@ START_TEST(schtasks)
create_file("test.xml", xml_a);
+ create_file("empty.xml", ""); + run_command_list(querylist, ARRAY_SIZE(querylist));
register_task("winetest"); @@ -286,6 +294,9 @@ START_TEST(schtasks)
run_command_list(creatlist, ARRAY_SIZE(creatlist));
+ r = DeleteFileA("empty.xml"); + ok(r, "DeleteFileA failed: %lu\n", GetLastError()); + r = DeleteFileA("test.xml"); ok(r, "DeleteFileA failed: %lu\n", GetLastError());
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143928
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
schtasks.exe: schtasks.c:226: Test failed: Expected 1, got = 0
=== w7u_el (32 bit report) ===
schtasks.exe: schtasks.c:226: Test failed: Expected 1, got = 0
=== w7pro64 (64 bit report) ===
schtasks.exe: schtasks.c:226: Test failed: Expected 1, got = 0