view ui/taskscheduler.cpp @ 1243:cf5784d2c3a8

(issue54) Safeguard to prohibit starting the application as root
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 24 Sep 2014 19:22:47 +0200
parents 8de162b91a22
children
line wrap: on
line source
#ifdef WIN32
#include "taskscheduler.h"

/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU GPL (v>=2)
 * and comes with ABSOLUTELY NO WARRANTY!
 * See LICENSE.txt for details.
 */

#include <windows.h>

#include <QDate>
#include <QDebug>
#include <QApplication>

#define TASK_NAME L"TrustBridge Update"

TaskScheduler::TaskScheduler() :
    mInitialized (false),
    mTaskScheduler (NULL)
{
    HRESULT hr;

    hr = CoInitialize(NULL);
    if(FAILED(hr)) {
        qDebug() << "TaskScheduler CoInitializeEx failed: " << hr;
        return;
    }

    hr = CoCreateInstance(CLSID_CTaskScheduler,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ITaskScheduler,
                          (void**)&mTaskScheduler);
    if(FAILED(hr)) {
        qDebug() << "TaskScheduler create instance failed: " << hr;
        CoUninitialize();
        return;
    }

    mInitialized = true;
    qDebug() << "Initialization done";
    return;
}

TaskScheduler::~TaskScheduler() {
    qDebug() << "TaskSched dtor;";

    if (!isInitialized()) {
        return;
    }
    mTaskScheduler->Release();
    CoUninitialize();
}

bool createTrigger(ITask *task, const QTime &startTime)
{
    ITaskTrigger *pITaskTrigger = NULL;
    WORD piNewTrigger = 0;
    HRESULT hr;
    TASK_TRIGGER pTrigger;
    ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER));
    QDate startdate = QDate::currentDate();

    if (!startTime.isValid() || task == NULL) {
        qDebug() << "Invalid args.";
        return false;
    }

    hr = task->CreateTrigger(&piNewTrigger,
            &pITaskTrigger);

    if (FAILED(hr)) {
        qDebug() << "Failed to create trigger.";
        return false;
    }

    pTrigger.wBeginDay = startdate.day();
    pTrigger.wBeginMonth = startdate.month();
    pTrigger.wBeginYear = startdate.year();
    pTrigger.wStartHour = startTime.hour();
    pTrigger.wStartMinute = startTime.minute();
    pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER);
    pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY;
    pTrigger.Type.Daily.DaysInterval = 1;

    hr = pITaskTrigger->SetTrigger(&pTrigger);

    pITaskTrigger->Release();
    if (FAILED(hr)) {
        qDebug() << "Failed to create trigger.";
        return false;
    }

    return true;
}

bool TaskScheduler::createDailyTask(const QString &executable,
                                    const QString &args,
                                    const QTime &startTime) {
    ITask *task = NULL;
    IPersistFile *persistFile = NULL;
    HRESULT hr;

    hr = mTaskScheduler->NewWorkItem(TASK_NAME,
            CLSID_CTask,
            IID_ITask,
            (IUnknown**)&task);

    if (FAILED(hr)) {
        qDebug() << "Failed to create new work item.";
        return false;
    }

    /* Set the task parameters */
    hr = task->SetApplicationName(reinterpret_cast<LPCWSTR> (executable.utf16()));
    if (FAILED(hr)) {
        qDebug() << "Failed to set application name.";
        task->Release();
        return false;
    }

    hr = task->SetParameters(reinterpret_cast<LPCWSTR> (args.utf16()));
    if (FAILED(hr)) {
        qDebug() << "Failed to set parameters.";
        task->Release();
        return false;
    }

    hr = task->SetComment(reinterpret_cast<LPCWSTR>(QObject::tr("TrustBridge automatic update check.").utf16()));
    if (FAILED(hr)) {
        qDebug() << "Failed to set comment.";
        task->Release();
        return false;
    }

    QString username = QString::fromLocal8Bit(qgetenv("USERNAME").constData());
    if (username.isEmpty()) {
        qDebug() << "Failed to obtain username from envrionment.";
        task->Release();
        return false;
    }

    hr = task->SetAccountInformation(reinterpret_cast<LPCWSTR>(username.utf16()), NULL);

    if (FAILED(hr)) {
        qDebug() << "Failed to set username.";
        task->Release();
        return false;
    }

    hr = task->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);

    if (FAILED(hr)) {
        qDebug() << "Failed to set flags.";
        task->Release();
        return false;
    }

    /* Now create the trigger for this task */
    if (!createTrigger(task, startTime)) {
        qDebug() << "Failed to create trigger.";
        task->Release();
        return false;
    }

    hr = task->QueryInterface(IID_IPersistFile,
                             (void **)&persistFile);
    task->Release();

    if (FAILED(hr)) {
        qDebug() << "Failed to get persist file interface.";
        task->Release();
        return false;
    }

    hr = persistFile->Save(NULL, TRUE);
    persistFile->Release();
    if (FAILED(hr)) {
        qDebug() << "Failed to save task";
        return false;
    }

    return true;
}
#endif /* WIN32 */

http://wald.intevation.org/projects/trustbridge/