schtasks/tests: Added /change command tests.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2018-01-05 23:12:48 +01:00 committed by Alexandre Julliard
parent a5af50c5db
commit 0219ebc537
4 changed files with 197 additions and 0 deletions

1
configure vendored
View File

@ -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

View File

@ -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])

View File

@ -0,0 +1,6 @@
TESTDLL = schtasks.exe
IMPORTS = ole32
C_SRCS = \
schtasks.c

View File

@ -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\">\n"
" <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();
}