/*
 * msiexec.exe implementation
 *
 * Copyright 2007 Google (James Hawkins)
 *
 * 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 WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msiexec);

static SERVICE_STATUS_HANDLE hstatus;

static HANDLE thread;
static HANDLE kill_event;

static void KillService(void)
{
    WINE_TRACE("Killing service\n");
    SetEvent(kill_event);
}

static BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
                            DWORD dwServiceSpecificExitCode)
{
    SERVICE_STATUS status;

    status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    status.dwCurrentState = dwCurrentState;

    if (dwCurrentState == SERVICE_START_PENDING)
        status.dwControlsAccepted = 0;
    else
    {
        status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
                                    SERVICE_ACCEPT_PAUSE_CONTINUE |
                                    SERVICE_ACCEPT_SHUTDOWN;
    }

    if (dwServiceSpecificExitCode == 0)
    {
        status.dwWin32ExitCode = dwWin32ExitCode;
    }
    else
    {
        status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
    }

    status.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
    status.dwCheckPoint = 0;
    status.dwWaitHint = 0;

    if (!SetServiceStatus(hstatus, &status))
    {
        fprintf(stderr, "Failed to set service status\n");
        KillService();
        return FALSE;
    }

    return TRUE;
}

static void WINAPI ServiceCtrlHandler(DWORD code)
{
    WINE_TRACE("%d\n", code);

    switch (code)
    {
        case SERVICE_CONTROL_SHUTDOWN:
        case SERVICE_CONTROL_STOP:
            UpdateSCMStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
            KillService();
            return;
        default:
            fprintf(stderr, "Unhandled service control code: %d\n", code);
            break;
    }

    UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);
}

static DWORD WINAPI ServiceExecutionThread(LPVOID param)
{
    while (TRUE)
    {
        /* do nothing */
    }

    return 0;
}

static BOOL StartServiceThread(void)
{
    DWORD id;

    thread = CreateThread(0, 0, ServiceExecutionThread, 0, 0, &id);
    if (!thread)
    {
        fprintf(stderr, "Failed to create thread\n");
        return FALSE;
    }

    return TRUE;
}

static void WINAPI ServiceMain(DWORD argc, LPSTR *argv)
{
    hstatus = RegisterServiceCtrlHandlerA("MSIServer", ServiceCtrlHandler);
    if (!hstatus)
    {
        fprintf(stderr, "Failed to register service ctrl handler\n");
        return;
    }

    UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0);

    kill_event = CreateEventW(0, TRUE, FALSE, 0);
    if (!kill_event)
    {
        fprintf(stderr, "Failed to create event\n");
        KillService();
        return;
    }

    if (!StartServiceThread())
    {
        KillService();
        return;
    }

    UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);

    WaitForSingleObject(kill_event, INFINITE);
    KillService();
}

DWORD DoService(void)
{
    char service_name[] = "MSIServer";

    const SERVICE_TABLE_ENTRYA service[] =
    {
        {service_name, ServiceMain},
        {NULL, NULL},
    };

    WINE_TRACE("Starting MSIServer service\n");

    if (!StartServiceCtrlDispatcherA(service))
    {
        fprintf(stderr, "Failed to start MSIServer service\n");
        return 1;
    }

    return 0;
}
