Sweden-Number/programs/schtasks/tests/schtasks.c

236 lines
6.8 KiB
C

/*
* 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 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";
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: %lu\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: %lu\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;
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: %08lx\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: %08lx\n", hres);
HeapFree(GetProcessHeap(), 0, task_name);
}
static void create_file(const char *file_name, const char *data)
{
HANDLE file;
DWORD size;
BOOL r;
file = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
if(file == INVALID_HANDLE_VALUE)
return;
r = WriteFile(file, data, strlen(data), &size, NULL);
ok(r, "WriteFile failed: %lu\n", GetLastError());
CloseHandle(file);
}
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: %08lx\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: %08lx\n", hres);
hres = ITaskService_GetFolder(service, NULL, &root);
ok(hres == S_OK, "GetFolder error %08lx\n", hres);
return TRUE;
}
START_TEST(schtasks)
{
static WCHAR wineW[] = L"\\wine";
static WCHAR wine_testW[] = L"\\wine\\test";
DWORD r;
CoInitialize(NULL);
if(!initialize_task_service()) {
CoUninitialize();
return;
}
r = run_command("schtasks");
ok(r == 0, "r = %lu\n", r);
register_task("winetest");
r = run_command("schtasks /change /tn winetest /enable");
ok(r == 0, "r = %lu\n", r);
unregister_task("winetest");
r = run_command("schtasks /change /tn winetest /enable");
ok(r == 1, "r = %lu\n", r);
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);
r = DeleteFileA("test.xml");
ok(r, "DeleteFileA failed: %lu\n", GetLastError());
ITaskFolder_DeleteFolder(root, wine_testW, 0);
ITaskFolder_DeleteFolder(root, wineW, 0);
ITaskFolder_Release(root);
ITaskService_Release(service);
CoUninitialize();
}