[PATCH v14 0/3] MR5151: schtasks: Ignore /tr /sc /rl options in create command.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47152 This is initial part which ignores the options. -- v14: 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. https://gitlab.winehq.org/wine/wine/-/merge_requests/5151
From: Vijay Kiran Kamuju <infyquest(a)gmail.com> --- programs/schtasks/schtasks.c | 69 ++++++++++++++++-------------- programs/schtasks/tests/schtasks.c | 22 ++++++++++ 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/programs/schtasks/schtasks.c b/programs/schtasks/schtasks.c index c9434801db8..10f17d7601b 100644 --- a/programs/schtasks/schtasks.c +++ b/programs/schtasks/schtasks.c @@ -111,7 +111,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) @@ -131,13 +131,13 @@ static int change_command(int argc, WCHAR *argv[]) while (argc) { if (!wcsicmp(argv[0], L"/tn")) { - if (argc < 2) { - FIXME("Missing /tn value\n"); + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /tn value\n"); return 1; } if (task_name) { - FIXME("Duplicated /tn argument\n"); + ERR("Duplicated /tn argument\n"); return 1; } @@ -150,8 +150,8 @@ static int change_command(int argc, WCHAR *argv[]) argc--; argv++; } else if (!wcsicmp(argv[0], L"/tr")) { - if (argc < 2) { - FIXME("Missing /tr value\n"); + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /tr value\n"); return 1; } @@ -159,19 +159,19 @@ static int change_command(int argc, WCHAR *argv[]) have_option = TRUE; argc -= 2; argv += 2; - }else { + } else { FIXME("Unsupported arguments %s\n", debugstr_w(argv[0])); return 1; } } if (!task_name) { - FIXME("Missing /tn option\n"); + ERR("Missing /tn option\n"); return 1; } if (!have_option) { - FIXME("Missing change options\n"); + ERR("Missing change options\n"); return 1; } @@ -204,28 +204,28 @@ static int create_command(int argc, WCHAR *argv[]) while (argc) { if (!wcsicmp(argv[0], L"/xml")) { - if (argc < 2) { - FIXME("Missing /xml value\n"); - return 1; + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /xml value\n"); + return E_FAIL; } if (xml_file) { - FIXME("Duplicated /xml argument\n"); - return 1; + ERR("Duplicated /xml argument\n"); + return E_FAIL; } 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 (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /tn value\n"); + return E_FAIL; } if (task_name) { - FIXME("Duplicated /tn argument\n"); - return 1; + ERR("Duplicated /tn argument\n"); + return E_FAIL; } task_name = argv[1]; @@ -236,33 +236,33 @@ static int create_command(int argc, WCHAR *argv[]) argc--; argv++; } else if (!wcsicmp(argv[0], L"/ru")) { - if (argc < 2) { - FIXME("Missing /ru value\n"); - return 1; + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /ru value\n"); + return E_FAIL; } FIXME("Unsupported /ru option %s\n", debugstr_w(argv[1])); argc -= 2; argv += 2; - }else { + } else { FIXME("Unsupported argument %s\n", debugstr_w(argv[0])); - return 1; + return E_FAIL; } } if (!task_name) { - FIXME("Missing /tn argument\n"); - return 1; + ERR("Missing /tn argument\n"); + return E_FAIL; } if (!xml_file) { - FIXME("Missing /xml argument\n"); + ERR("Missing /xml argument\n"); return E_FAIL; } xml = read_file_to_bstr(xml_file); if (!xml) - return 1; + return E_FAIL; root = get_tasks_root_folder(); if (!root) { @@ -297,27 +297,27 @@ static int delete_command(int argc, WCHAR *argv[]) argc--; argv++; } else if (!wcsicmp(argv[0], L"/tn")) { - if (argc < 2) { - FIXME("Missing /tn value\n"); + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /tn value\n"); return 1; } if (task_name) { - FIXME("Duplicated /tn argument\n"); + ERR("Duplicated /tn argument\n"); return 1; } task_name = argv[1]; argc -= 2; argv += 2; - }else { + } else { FIXME("Unsupported argument %s\n", debugstr_w(argv[0])); return 1; } } if (!task_name) { - FIXME("Missing /tn argument\n"); + ERR("Missing /tn argument\n"); return 1; } @@ -354,7 +354,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..e896449fa32 100644 --- a/programs/schtasks/tests/schtasks.c +++ b/programs/schtasks/tests/schtasks.c @@ -222,11 +222,17 @@ START_TEST(schtasks) r = run_command("schtasks"); ok(r == 0, "r = %lu\n", r); + r = run_command("schtasks /wine"); + ok(r == 1, "r = %lu\n", r); + register_task("winetest"); r = run_command("schtasks /change /tn winetest /enable"); ok(r == 0, "r = %lu\n", r); + r = run_command("schtasks /change /tn winetest /tn /enable"); + ok(r == 1, "r = %lu\n", r); + unregister_task("winetest"); r = run_command("schtasks /change /tn winetest /enable"); @@ -237,6 +243,9 @@ START_TEST(schtasks) r = run_command("schtasks /CHANGE /tn wine\\test\\winetest /enable"); ok(r == 0, "r = %lu\n", r); + r = run_command("schtasks /delete /f /tn /tn wine\\test\\winetest"); + ok(r == 1, "r = %lu\n", r); + r = run_command("schtasks /delete /f /tn wine\\test\\winetest"); ok(r == 0, "r = %lu\n", r); @@ -248,6 +257,18 @@ START_TEST(schtasks) r = run_command("schtasks /create /xml test.xml /tn wine\\winetest"); ok(r == 0, "r = %lu\n", r); + r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /tn"); + ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ + + r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /xml"); + ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ + + r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /tn test"); + ok(r == E_FAIL, "r = %lx\n", r); /* duplicate arguments */ + + r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /xml empty.xml"); + ok(r == E_FAIL, "r = %lx\n", r); /* duplicate arguments */ + r = run_command("schtasks /change /tn wine\\winetest /enable"); ok(r == 0, "r = %lu\n", r); @@ -268,6 +289,7 @@ START_TEST(schtasks) 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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5151
From: Vijay Kiran Kamuju <infyquest(a)gmail.com> --- programs/schtasks/schtasks.c | 109 +++++++++++++++++++++++------ programs/schtasks/tests/schtasks.c | 22 +++++- 2 files changed, 107 insertions(+), 24 deletions(-) diff --git a/programs/schtasks/schtasks.c b/programs/schtasks/schtasks.c index 10f17d7601b..bb52e7e7bc0 100644 --- a/programs/schtasks/schtasks.c +++ b/programs/schtasks/schtasks.c @@ -194,13 +194,14 @@ static int change_command(int argc, WCHAR *argv[]) static int create_command(int argc, WCHAR *argv[]) { - const WCHAR *task_name = NULL, *xml_file = NULL; + const WCHAR *task_name = NULL, *xml_file = NULL, *task_run = NULL, *schedule = NULL; ITaskFolder *root = NULL; LONG flags = TASK_CREATE; IRegisteredTask *task; VARIANT empty; BSTR str, xml; HRESULT hres; + BOOL xml_mode = FALSE, tr_mode = FALSE; while (argc) { if (!wcsicmp(argv[0], L"/xml")) { @@ -215,6 +216,7 @@ static int create_command(int argc, WCHAR *argv[]) } xml_file = argv[1]; + xml_mode = TRUE; argc -= 2; argv += 2; } else if (!wcsicmp(argv[0], L"/tn")) { @@ -231,6 +233,48 @@ static int create_command(int argc, WCHAR *argv[]) task_name = argv[1]; argc -= 2; argv += 2; + } else if (!wcsicmp(argv[0], L"/tr")) { + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /tr value\n"); + return E_FAIL; + } + + if (task_run) { + ERR("Duplicated /tr argument\n"); + return E_FAIL; + } + + FIXME("Unsupported /tr option %s\n", debugstr_w(argv[1])); + task_run = argv[1]; + tr_mode = TRUE; + argc -= 2; + argv += 2; + } else if (!wcsicmp(argv[0], L"/sc")) { + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /sc value\n"); + return E_FAIL; + } + + if (schedule) { + ERR("Duplicated /sc argument\n"); + return E_FAIL; + } + + FIXME("Unsupported /sc option %s\n", debugstr_w(argv[1])); + schedule = argv[1]; + tr_mode = TRUE; + argc -= 2; + argv += 2; + } else if (!wcsicmp(argv[0], L"/rl")) { + if (argc < 2 || !wcsncmp(argv[1], L"/", 1)) { + ERR("Missing /rl value\n"); + return E_FAIL; + } + + FIXME("Unsupported /rl option %s\n", debugstr_w(argv[1])); + tr_mode = TRUE; + argc -= 2; + argv += 2; } else if (!wcsicmp(argv[0], L"/f")) { flags = TASK_CREATE_OR_UPDATE; argc--; @@ -255,33 +299,54 @@ static int create_command(int argc, WCHAR *argv[]) return E_FAIL; } - if (!xml_file) { - ERR("Missing /xml argument\n"); - return E_FAIL; - } + if (xml_mode) { + if (tr_mode) { + ERR("/xml option can only be used with /ru /f /tn\n"); + return E_FAIL; + } - xml = read_file_to_bstr(xml_file); - if (!xml) - return E_FAIL; + if (!xml_file) { + ERR("Missing /xml argument\n"); + return E_FAIL; + } - root = get_tasks_root_folder(); - if (!root) { + xml = read_file_to_bstr(xml_file); + if (!xml) + return 1; + + root = get_tasks_root_folder(); + if (!root) { + SysFreeString(xml); + return 1; + } + + V_VT(&empty) = VT_EMPTY; + str = SysAllocString(task_name); + hres = ITaskFolder_RegisterTask(root, str, xml, flags, empty, empty, + TASK_LOGON_NONE, empty, &task); + SysFreeString(str); SysFreeString(xml); - return 1; + ITaskFolder_Release(root); + if (FAILED(hres)) + return 1; + + IRegisteredTask_Release(task); + return 0; } - V_VT(&empty) = VT_EMPTY; - str = SysAllocString(task_name); - 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; + if (tr_mode) { + if (!task_run) { + ERR("Missing /tr argument\n"); + return E_FAIL; + } - IRegisteredTask_Release(task); - return 0; + if (!schedule) { + ERR("Missing /sc argument\n"); + return E_FAIL; + } + 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 e896449fa32..248dd1b8c1e 100644 --- a/programs/schtasks/tests/schtasks.c +++ b/programs/schtasks/tests/schtasks.c @@ -269,20 +269,38 @@ START_TEST(schtasks) r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /xml empty.xml"); ok(r == E_FAIL, "r = %lx\n", r); /* duplicate arguments */ + r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /tr c:\\windows\\hh.exe"); + ok(r == E_FAIL, "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 /f /tn wine\\winetest /tr c:\\windows\\hh.exe"); + ok(r == E_FAIL, "r = %lu\n", r); /* tr argument provided along with xml argument */ + 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 /Delete /f /tn wine\\winetest"); + ok(r == 0, "r = %lu\n", r); + 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); + r = run_command("schtasks /create /tn wine\\winetest /tr c:\\windows\\hh.exe"); + ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ + + r = run_command("schtasks /create /tn wine\\winetest /tr c:\\windows\\hh.exe /sc wine"); + ok(r == E_FAIL, "r = %lx\n", r); /* invalid schedule */ + + r = run_command("schtasks /create /tn wine\\winetest /tr c:\\windows\\hh.exe /sc daily"); + todo_wine ok(r == 0, "r = %lx\n", r); /* daily schedule */ + + r = run_command("schtasks /DELETE /f /tn wine\\winetest"); + todo_wine ok(r == 0, "r = %lu\n", r); r = DeleteFileA("test.xml"); ok(r, "DeleteFileA failed: %lu\n", GetLastError()); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5151
From: Vijay Kiran Kamuju <infyquest(a)gmail.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47152 --- programs/schtasks/schtasks.c | 27 +++++++++++++++++++++++++-- programs/schtasks/tests/schtasks.c | 26 +++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/programs/schtasks/schtasks.c b/programs/schtasks/schtasks.c index bb52e7e7bc0..a5be5ce3ec4 100644 --- a/programs/schtasks/schtasks.c +++ b/programs/schtasks/schtasks.c @@ -244,7 +244,6 @@ static int create_command(int argc, WCHAR *argv[]) return E_FAIL; } - FIXME("Unsupported /tr option %s\n", debugstr_w(argv[1])); task_run = argv[1]; tr_mode = TRUE; argc -= 2; @@ -260,7 +259,6 @@ static int create_command(int argc, WCHAR *argv[]) return E_FAIL; } - FIXME("Unsupported /sc option %s\n", debugstr_w(argv[1])); schedule = argv[1]; tr_mode = TRUE; argc -= 2; @@ -340,12 +338,37 @@ static int create_command(int argc, WCHAR *argv[]) return E_FAIL; } + FIXME("Unsupported /tr option %s\n", wine_dbgstr_w(task_run)); if (!schedule) { ERR("Missing /sc argument\n"); return E_FAIL; + } else if (!wcsicmp(schedule, L"minute")){ + FIXME("Unsupported /sc minute\n"); + } else if (!wcsicmp(schedule, L"hourly")){ + FIXME("Unsupported /sc hourly\n"); + } else if (!wcsicmp(schedule, L"daily")){ + FIXME("Unsupported /sc daily\n"); + } else if (!wcsicmp(schedule, L"weekly")){ + FIXME("Unsupported /sc weekly\n"); + } else if (!wcsicmp(schedule, L"monthly")){ + FIXME("Unsupported /sc monthly\n"); + } else if (!wcsicmp(schedule, L"once")){ + FIXME("Unsupported /sc once\n"); + } else if (!wcsicmp(schedule, L"onstart")){ + FIXME("Unsupported /sc onstart\n"); + } else if (!wcsicmp(schedule, L"onlogon")){ + FIXME("Unsupported /sc onlogon\n"); + } else if (!wcsicmp(schedule, L"onidle")){ + FIXME("Unsupported /sc onidle\n"); + } else if (!wcsicmp(schedule, L"onevent")){ + FIXME("Unsupported /sc onevent\n"); + } else { + ERR("Invalid schedule type %s\n", debugstr_w(schedule)); + return E_FAIL; } return 0; } + return E_FAIL; } diff --git a/programs/schtasks/tests/schtasks.c b/programs/schtasks/tests/schtasks.c index 248dd1b8c1e..f92333af9f2 100644 --- a/programs/schtasks/tests/schtasks.c +++ b/programs/schtasks/tests/schtasks.c @@ -254,8 +254,16 @@ START_TEST(schtasks) create_file("test.xml", xml_a); - r = run_command("schtasks /create /xml test.xml /tn wine\\winetest"); - ok(r == 0, "r = %lu\n", r); + create_file("empty.xml", ""); + + r = run_command("schtasks /create /xml test.xml"); + ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ + + r = run_command("schtasks /create /xml test.xml /tn"); + ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ + + r = run_command("schtasks /create /xml /tn wine\\winetest"); + ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /tn"); ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ @@ -269,6 +277,12 @@ START_TEST(schtasks) r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /xml empty.xml"); ok(r == E_FAIL, "r = %lx\n", r); /* duplicate arguments */ + r = run_command("schtasks /create /xml test.xml /tn wine\\winetest"); + ok(r == 0, "r = %lu\n", r); + + r = run_command("schtasks /create /xml empty.xml /tn wine\\winetest"); + ok(r == 1, "r = %lu\n", r); + r = run_command("schtasks /create /xml test.xml /tn wine\\winetest /tr c:\\windows\\hh.exe"); ok(r == E_FAIL, "r = %lu\n", r); @@ -290,6 +304,9 @@ START_TEST(schtasks) r = run_command("schtasks /create /tn wine\\winetest"); ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ + r = run_command("schtasks /create /tn"); + ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ + r = run_command("schtasks /create /tn wine\\winetest /tr c:\\windows\\hh.exe"); ok(r == E_FAIL, "r = %lx\n", r); /* missing arguments */ @@ -297,11 +314,14 @@ START_TEST(schtasks) ok(r == E_FAIL, "r = %lx\n", r); /* invalid schedule */ r = run_command("schtasks /create /tn wine\\winetest /tr c:\\windows\\hh.exe /sc daily"); - todo_wine ok(r == 0, "r = %lx\n", r); /* daily schedule */ + ok(r == 0, "r = %lx\n", r); /* daily schedule */ r = run_command("schtasks /DELETE /f /tn wine\\winetest"); todo_wine ok(r == 0, "r = %lu\n", r); + r = DeleteFileA("empty.xml"); + ok(r, "DeleteFileA failed: %lu\n", GetLastError()); + r = DeleteFileA("test.xml"); ok(r, "DeleteFileA failed: %lu\n", GetLastError()); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5151
On Wed Feb 28 06:57:50 2024 +0000, Vijay Kiran Kamuju wrote:
I just followed the existing pattern in the code. I can change it to a WARN, but it needs to be changed a lot places in this program and it warrants a separate MR as we also need to change how the errors are shown on command line and error messages dont match the native windows. I have changed the FIXME's to ERR's as they are actually error messages.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5151#note_63080
This needs to use some kind of table, both in the code and in the tests, instead of copy/pasting the same thing a dozen times. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5151#note_63116
participants (3)
-
Alexandre Julliard (@julliard) -
Vijay Kiran Kamuju -
Vijay Kiran Kamuju (@infyquest)