Module: wine Branch: master Commit: 0219ebc5377a439ed8991f1fcdbbf5673dcfa843 URL: https://source.winehq.org/git/wine.git/?a=commit;h=0219ebc5377a439ed8991f1fc...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Jan 5 23:12:48 2018 +0100
schtasks/tests: Added /change command tests.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
configure | 1 + configure.ac | 1 + programs/schtasks/tests/Makefile.in | 6 ++ programs/schtasks/tests/schtasks.c | 189 ++++++++++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+)
diff --git a/configure b/configure index 424b2e3..399bc3b 100755 --- a/configure +++ b/configure @@ -19154,6 +19154,7 @@ wine_fn_config_program rundll.exe16 enable_win16 install wine_fn_config_program rundll32 enable_rundll32 install wine_fn_config_program sc enable_sc install wine_fn_config_program schtasks enable_schtasks install +wine_fn_config_test programs/schtasks/tests schtasks.exe_test wine_fn_config_program sdbinst enable_sdbinst install wine_fn_config_program secedit enable_secedit install wine_fn_config_program servicemodelreg enable_servicemodelreg install diff --git a/configure.ac b/configure.ac index 62ad8db..9aa3228 100644 --- a/configure.ac +++ b/configure.ac @@ -3793,6 +3793,7 @@ WINE_CONFIG_PROGRAM(rundll.exe16,enable_win16,[install]) WINE_CONFIG_PROGRAM(rundll32,,[install]) WINE_CONFIG_PROGRAM(sc,,[install]) WINE_CONFIG_PROGRAM(schtasks,,[install]) +WINE_CONFIG_TEST(programs/schtasks/tests) WINE_CONFIG_PROGRAM(sdbinst,,[install]) WINE_CONFIG_PROGRAM(secedit,,[install]) WINE_CONFIG_PROGRAM(servicemodelreg,,[install]) diff --git a/programs/schtasks/tests/Makefile.in b/programs/schtasks/tests/Makefile.in new file mode 100644 index 0000000..dcf641c --- /dev/null +++ b/programs/schtasks/tests/Makefile.in @@ -0,0 +1,6 @@ +TESTDLL = schtasks.exe +IMPORTS = ole32 + + +C_SRCS = \ + schtasks.c diff --git a/programs/schtasks/tests/schtasks.c b/programs/schtasks/tests/schtasks.c new file mode 100644 index 0000000..b8a9739 --- /dev/null +++ b/programs/schtasks/tests/schtasks.c @@ -0,0 +1,189 @@ +/* + * Copyright 2018 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "initguid.h" +#include "taskschd.h" + +#include "wine/test.h" + +static ITaskService *service; +static ITaskFolder *root; + +static WCHAR *a2w(const char *str) +{ + WCHAR *ret; + int len; + + if(!str) + return NULL; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + + return ret; +} + +#define run_command(a) _run_command(__LINE__,a) +static DWORD _run_command(unsigned line, const char *cmd) +{ + STARTUPINFOA si = {sizeof(STARTUPINFOA)}; + PROCESS_INFORMATION pi; + char command[1024]; + BOOL r; + DWORD ret; + + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = INVALID_HANDLE_VALUE; + si.hStdOutput = INVALID_HANDLE_VALUE; + si.hStdError = INVALID_HANDLE_VALUE; + + strcpy(command, cmd); + r = CreateProcessA(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); + ok_(__FILE__,line)(r, "CreateProcess failed: %u\n", GetLastError()); + if(!r) return -1; + + ret = WaitForSingleObject(pi.hProcess, 10000); + ok_(__FILE__,line)(ret == WAIT_OBJECT_0, "wait failed\n"); + if (ret == WAIT_TIMEOUT) + TerminateProcess(pi.hProcess, -1); + + r = GetExitCodeProcess(pi.hProcess, &ret); + ok_(__FILE__,line)(r, "GetExitCodeProcess failed: %u\n", GetLastError()); + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + return ret; +} + +#define register_task(a) _register_task(__LINE__,a) +static void _register_task(unsigned line, const char *task_name_a) +{ + IRegisteredTask *task; + VARIANT empty; + WCHAR *task_name, *xml; + HRESULT hres; + + 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" + " <RegistrationInfo>\n" + " <Description>"Task1"</Description>\n" + " </RegistrationInfo>\n" + " <Settings>\n" + " <Enabled>false</Enabled>\n" + " <Hidden>false</Hidden>\n" + " </Settings>\n" + " <Actions>\n" + " <Exec>\n" + " <Command>"task1.exe"</Command>\n" + " </Exec>\n" + " </Actions>\n" + "</Task>\n"; + + V_VT(&empty) = VT_EMPTY; + task_name = a2w(task_name_a); + xml = a2w(xml_a); + + /* make sure it's not registered */ + ITaskFolder_DeleteTask(root, task_name, 0); + + hres = ITaskFolder_RegisterTask(root, task_name, xml, TASK_CREATE, empty, empty, + TASK_LOGON_NONE, empty, &task); + ok_(__FILE__,line)(hres == S_OK, "RegisterTask failed: %08x\n", hres); + HeapFree(GetProcessHeap(), 0, task_name); + HeapFree(GetProcessHeap(), 0, xml); + + IRegisteredTask_Release(task); +} + +#define unregister_task(a) _unregister_task(__LINE__,a) +static void _unregister_task(unsigned line, const char *task_name_a) +{ + WCHAR *task_name; + HRESULT hres; + + task_name = a2w(task_name_a); + + hres = ITaskFolder_DeleteTask(root, task_name, 0); + ok_(__FILE__,line)(hres == S_OK, "DeleteTask failed: %08x\n", hres); + + HeapFree(GetProcessHeap(), 0, task_name); +} + +static BOOL initialize_task_service(void) +{ + VARIANT empty; + HRESULT hres; + + hres = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, + &IID_ITaskService, (void **)&service); + if(hres != S_OK) { + ok(hres == REGDB_E_CLASSNOTREG, "Could not create task service: %08x\n", hres); + win_skip("Task service not available\n"); + return FALSE; + } + + V_VT(&empty) = VT_EMPTY; + hres = ITaskService_Connect(service, empty, empty, empty, empty); + ok(hres == S_OK, "Connect failed: %08x\n", hres); + + hres = ITaskService_GetFolder(service, NULL, &root); + ok(hres == S_OK, "GetFolder error %08x\n", hres); + return TRUE; +} + +START_TEST(schtasks) +{ + DWORD r; + + CoInitialize(NULL); + if(!initialize_task_service()) { + CoUninitialize(); + return; + } + + r = run_command("schtasks"); + ok(r == 0, "r = %u\n", r); + + register_task("winetest"); + + r = run_command("schtasks /change /tn winetest /enable"); + ok(r == 0, "r = %u\n", r); + + unregister_task("winetest"); + + r = run_command("schtasks /change /tn winetest /enable"); + ok(r == 1, "r = %u\n", r); + + register_task("wine\test\winetest"); + + r = run_command("schtasks /change /tn wine\test\winetest /enable"); + ok(r == 0, "r = %u\n", r); + + unregister_task("wine\test\winetest"); + + r = run_command("schtasks /change /tn wine\test\winetest /enable"); + ok(r == 1, "r = %u\n", r); + + ITaskFolder_Release(root); + ITaskService_Release(service); + CoUninitialize(); +}