/*
 * Task Scheduler Service
 *
 * Copyright 2014 Dmitry Timoshkov
 *
 * 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
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winsvc.h"
#include "rpc.h"
#include "schrpc.h"
#include "wine/debug.h"

#include "schedsvc_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);

static const WCHAR scheduleW[] = {'S','c','h','e','d','u','l','e',0};
static SERVICE_STATUS_HANDLE schedsvc_handle;
static HANDLE done_event;

void schedsvc_auto_start(void)
{
    static DWORD start_type;
    SC_HANDLE scm, service;
    QUERY_SERVICE_CONFIGW *cfg;
    DWORD cfg_size;

    if (start_type == SERVICE_AUTO_START) return;

    TRACE("changing service start type to SERVICE_AUTO_START\n");

    scm = OpenSCManagerW(NULL, NULL, 0);
    if (!scm)
    {
        WARN("failed to open SCM (%u)\n", GetLastError());
        return;
    }

    service = OpenServiceW(scm, scheduleW, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
    if (service)
    {
        if (!QueryServiceConfigW(service, NULL, 0, &cfg_size) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
            cfg = HeapAlloc(GetProcessHeap(), 0, cfg_size);
            if (cfg)
            {
                if (QueryServiceConfigW(service, cfg, cfg_size, &cfg_size))
                {
                    start_type = cfg->dwStartType;
                    if (start_type != SERVICE_AUTO_START)
                    {
                        if (ChangeServiceConfigW(service, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
                                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL))
                            start_type = SERVICE_AUTO_START;
                    }
                }
                HeapFree(GetProcessHeap(), 0, cfg);
            }
        }
        else
            WARN("failed to query service config (%u)\n", GetLastError());

        CloseServiceHandle(service);
    }
    else
        WARN("failed to open service (%u)\n", GetLastError());

    CloseServiceHandle(scm);
}

static void schedsvc_update_status(DWORD state)
{
    SERVICE_STATUS status;

    status.dwServiceType = SERVICE_WIN32;
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    status.dwWin32ExitCode = 0;
    status.dwServiceSpecificExitCode = 0;
    status.dwCheckPoint = 0;
    status.dwWaitHint = 0;
    status.dwControlsAccepted = 0;
    status.dwCurrentState = state;

    SetServiceStatus(schedsvc_handle, &status);
}

static void WINAPI schedsvc_handler(DWORD control)
{
    TRACE("%#x\n", control);

    switch (control)
    {
    case SERVICE_CONTROL_STOP:
    case SERVICE_CONTROL_SHUTDOWN:
        schedsvc_update_status(SERVICE_STOP_PENDING);
        SetEvent(done_event);
        break;

    default:
        schedsvc_update_status(SERVICE_RUNNING);
        break;
    }
}

static RPC_BINDING_VECTOR *sched_bindings;

static RPC_STATUS RPC_init(void)
{
    WCHAR transport[] = SCHEDSVC_TRANSPORT;
    RPC_STATUS status;

    TRACE("using %s\n", debugstr_w(transport));

    status = RpcServerUseProtseqEpW(transport, 0, NULL, NULL);
    if (status != RPC_S_OK)
    {
        ERR("RpcServerUseProtseqEp error %#x\n", status);
        return status;
    }

    status = RpcServerRegisterIf(ITaskSchedulerService_v1_0_s_ifspec, 0, 0);
    if (status != RPC_S_OK)
    {
        ERR("RpcServerRegisterIf error %#x\n", status);
        return status;
    }

    status = RpcServerInqBindings(&sched_bindings);
    if (status != RPC_S_OK)
    {
        ERR("RpcServerInqBindings error %#x\n", status);
        return status;
    }

    status = RpcEpRegisterW(ITaskSchedulerService_v1_0_s_ifspec, sched_bindings, NULL, NULL);
    if (status != RPC_S_OK)
    {
        ERR("RpcEpRegister error %#x\n", status);
        return status;
    }

    status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE);
    if (status != RPC_S_OK)
    {
        ERR("RpcServerListen error %#x\n", status);
        return status;
    }
    return RPC_S_OK;
}

static void RPC_finish(void)
{
    RpcMgmtStopServerListening(NULL);
    RpcEpUnregister(ITaskSchedulerService_v1_0_s_ifspec, sched_bindings, NULL);
    RpcBindingVectorFree(&sched_bindings);
    RpcServerUnregisterIf(NULL, NULL, FALSE);
}

void WINAPI ServiceMain(DWORD argc, LPWSTR *argv)
{
    TRACE("starting Task Scheduler Service\n");

    schedsvc_handle = RegisterServiceCtrlHandlerW(scheduleW, schedsvc_handler);
    if (!schedsvc_handle)
    {
        ERR("RegisterServiceCtrlHandler error %d\n", GetLastError());
        return;
    }

    done_event = CreateEventW(NULL, TRUE, FALSE, NULL);

    schedsvc_update_status(SERVICE_START_PENDING);

    if (RPC_init() == RPC_S_OK)
    {
        schedsvc_update_status(SERVICE_RUNNING);
        WaitForSingleObject(done_event, INFINITE);
        RPC_finish();
    }

    schedsvc_update_status(SERVICE_STOPPED);

    TRACE("exiting Task Scheduler Service\n");
}

void  __RPC_FAR * __RPC_USER MIDL_user_allocate(SIZE_T len)
{
    return heap_alloc(len);
}

void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr)
{
    heap_free(ptr);
}
