schtests: Added /create command implementation.

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-19 19:16:29 +01:00 committed by Alexandre Julliard
parent c6f66c6b98
commit 74b386d4a2
2 changed files with 182 additions and 17 deletions

View File

@ -27,10 +27,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(schtasks);
static const WCHAR change_optW[] = {'/','c','h','a','n','g','e',0};
static const WCHAR create_optW[] = {'/','c','r','e','a','t','e',0};
static const WCHAR delete_optW[] = {'/','d','e','l','e','t','e',0};
static const WCHAR enable_optW[] = {'/','e','n','a','b','l','e',0};
static const WCHAR f_optW[] = {'/','f',0};
static const WCHAR tn_optW[] = {'/','t','n',0};
static const WCHAR xml_optW[] = {'/','x','m','l',0};
static ITaskFolder *get_tasks_root_folder(void)
{
@ -84,6 +86,51 @@ static IRegisteredTask *get_registered_task(const WCHAR *name)
return registered_task;
}
static BSTR read_file_to_bstr(const WCHAR *file_name)
{
LARGE_INTEGER file_size;
DWORD read_size, size;
unsigned char *data;
HANDLE file;
BOOL r = FALSE;
BSTR ret;
file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
FIXME("Could not open file\n");
return NULL;
}
if (!GetFileSizeEx(file, &file_size) || !file_size.QuadPart) {
FIXME("Empty file\n");
CloseHandle(file);
return NULL;
}
data = HeapAlloc(GetProcessHeap(), 0, file_size.QuadPart);
if (data)
r = ReadFile(file, data, file_size.QuadPart, &read_size, NULL);
CloseHandle(file);
if (!r) {
FIXME("Read filed\n");
HeapFree(GetProcessHeap(), 0, data);
return NULL;
}
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 {
size = MultiByteToWideChar(CP_ACP, 0, (const char *)data, read_size, NULL, 0);
ret = SysAllocStringLen(NULL, size);
if (ret)
MultiByteToWideChar(CP_ACP, 0, (const char *)data, read_size, ret, size);
}
HeapFree(GetProcessHeap(), 0, data);
return ret;
}
static int change_command(int argc, WCHAR *argv[])
{
const WCHAR *task_name;
@ -132,6 +179,84 @@ static int change_command(int argc, WCHAR *argv[])
return 0;
}
static int create_command(int argc, WCHAR *argv[])
{
const WCHAR *task_name = NULL, *xml_file = NULL;
ITaskFolder *root = NULL;
IRegisteredTask *task;
VARIANT empty;
BSTR str, xml;
HRESULT hres;
while (argc) {
if (!strcmpiW(argv[0], xml_optW)) {
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(!strcmpiW(argv[0], tn_optW)) {
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 (!task_name) {
FIXME("Missing /tn argument\n");
return 1;
}
if (!xml_file) {
FIXME("Missing /xml argument\n");
return E_FAIL;
}
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, TASK_CREATE, empty, empty,
TASK_LOGON_NONE, empty, &task);
SysFreeString(str);
SysFreeString(xml);
ITaskFolder_Release(root);
if (FAILED(hres))
return 1;
IRegisteredTask_Release(task);
return 0;
}
static int delete_command(int argc, WCHAR *argv[])
{
const WCHAR *task_name = NULL;
@ -197,6 +322,8 @@ int wmain(int argc, WCHAR *argv[])
FIXME("Print current tasks state\n");
else if (!strcmpiW(argv[1], change_optW))
ret = change_command(argc - 2, argv + 2);
else if (!strcmpiW(argv[1], create_optW))
ret = create_command(argc - 2, argv + 2);
else if (!strcmpiW(argv[1], delete_optW))
ret = delete_command(argc - 2, argv + 2);
else

View File

@ -26,6 +26,23 @@
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;
@ -81,23 +98,6 @@ static void _register_task(unsigned line, const char *task_name_a)
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);
@ -128,6 +128,23 @@ static void _unregister_task(unsigned line, const char *task_name_a)
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: %u\n", GetLastError());
CloseHandle(file);
}
static BOOL initialize_task_service(void)
{
VARIANT empty;
@ -186,8 +203,29 @@ START_TEST(schtasks)
r = run_command("schtasks /Change /tn wine\\test\\winetest /enable");
ok(r == 1, "r = %u\n", r);
create_file("test.xml", xml_a);
r = run_command("schtasks /create /xml test.xml /tn wine\\winetest");
ok(r == 0, "r = %u\n", r);
r = run_command("schtasks /change /tn wine\\winetest /enable");
ok(r == 0, "r = %u\n", r);
r = run_command("schtasks /create /xml test.xml /tn wine\\winetest");
ok(r == 1, "r = %u\n", r); /* task already exists */
r = run_command("schtasks /create /tn wine\\winetest");
ok(r == E_FAIL, "r = %x\n", r); /* missing arguments */
r = run_command("schtasks /Delete /f /tn wine\\winetest");
ok(r == 0, "r = %u\n", r);
r = DeleteFileA("test.xml");
ok(r, "DeleteFileA failed: %u\n", GetLastError());
ITaskFolder_DeleteFolder(root, wine_testW, 0);
ITaskFolder_DeleteFolder(root, wineW, 0);
ITaskFolder_Release(root);
ITaskService_Release(service);
CoUninitialize();