/*
 *  openvpnmsica -- Custom Action DLL to provide OpenVPN-specific support to MSI packages
 *                  https://community.openvpn.net/openvpn/wiki/OpenVPNMSICA
 *
 *  Copyright (C) 2018 Simon Rozman <simon@rozman.si>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#elif defined(_MSC_VER)
#include <config-msvc.h>
#endif

#include "openvpnmsica.h"
#include "../tapctl/error.h"

#include <windows.h>
#include <msi.h>
#include <msiquery.h>
#ifdef _MSC_VER
#pragma comment(lib, "msi.lib")
#endif
#include <stdio.h>
#include <tchar.h>


DWORD openvpnmsica_thread_data_idx = TLS_OUT_OF_INDEXES;


/**
 * DLL entry point
 */
BOOL WINAPI
DllMain(
    _In_ HINSTANCE hinstDLL,
    _In_ DWORD dwReason,
    _In_ LPVOID lpReserved)
{
    UNREFERENCED_PARAMETER(hinstDLL);
    UNREFERENCED_PARAMETER(lpReserved);

    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            /* Allocate thread local storage index. */
            openvpnmsica_thread_data_idx = TlsAlloc();
            if (openvpnmsica_thread_data_idx == TLS_OUT_OF_INDEXES)
            {
                return FALSE;
            }
        /* Fall through. */

        case DLL_THREAD_ATTACH:
        {
            /* Create thread local storage data. */
            struct openvpnmsica_thread_data *s = (struct openvpnmsica_thread_data *)calloc(1, sizeof(struct openvpnmsica_thread_data));
            if (s == NULL)
            {
                return FALSE;
            }

            TlsSetValue(openvpnmsica_thread_data_idx, s);
            break;
        }

        case DLL_PROCESS_DETACH:
            if (openvpnmsica_thread_data_idx != TLS_OUT_OF_INDEXES)
            {
                /* Free thread local storage data and index. */
                free(TlsGetValue(openvpnmsica_thread_data_idx));
                TlsFree(openvpnmsica_thread_data_idx);
            }
            break;

        case DLL_THREAD_DETACH:
            /* Free thread local storage data. */
            free(TlsGetValue(openvpnmsica_thread_data_idx));
            break;
    }

    return TRUE;
}


bool
dont_mute(unsigned int flags)
{
    UNREFERENCED_PARAMETER(flags);

    return true;
}


void
x_msg_va(const unsigned int flags, const char *format, va_list arglist)
{
    /* Secure last error before it is overridden. */
    DWORD dwResult = (flags & M_ERRNO) != 0 ? GetLastError() : ERROR_SUCCESS;

    struct openvpnmsica_thread_data *s = (struct openvpnmsica_thread_data *)TlsGetValue(openvpnmsica_thread_data_idx);
    if (s->hInstall == 0)
    {
        /* No MSI session, no fun. */
        return;
    }

    /* Prepare the message record. The record will contain up to four fields. */
    MSIHANDLE hRecordProg = MsiCreateRecord(4);

    {
        /* Field 2: The message string. */
        char szBufStack[128];
        int iResultLen = vsnprintf(szBufStack, _countof(szBufStack), format, arglist);
        if (iResultLen < _countof(szBufStack))
        {
            /* Use from stack. */
            MsiRecordSetStringA(hRecordProg, 2, szBufStack);
        }
        else
        {
            /* Allocate on heap and retry. */
            char *szMessage = (char *)malloc(++iResultLen * sizeof(char));
            if (szMessage != NULL)
            {
                vsnprintf(szMessage, iResultLen, format, arglist);
                MsiRecordSetStringA(hRecordProg, 2, szMessage);
                free(szMessage);
            }
            else
            {
                /* Use stack variant anyway, but make sure it's zero-terminated. */
                szBufStack[_countof(szBufStack) - 1] = 0;
                MsiRecordSetStringA(hRecordProg, 2, szBufStack);
            }
        }
    }

    if ((flags & M_ERRNO) == 0)
    {
        /* Field 1: MSI Error Code */
        MsiRecordSetInteger(hRecordProg, 1, ERROR_MSICA);
    }
    else
    {
        /* Field 1: MSI Error Code */
        MsiRecordSetInteger(hRecordProg, 1, ERROR_MSICA_ERRNO);

        /* Field 3: The Windows error number. */
        MsiRecordSetInteger(hRecordProg, 3, dwResult);

        /* Field 4: The Windows error description. */
        LPTSTR szErrMessage = NULL;
        if (FormatMessage(
                FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
                0,
                dwResult,
                0,
                (LPTSTR)&szErrMessage,
                0,
                NULL) && szErrMessage)
        {
            /* Trim trailing whitespace. Set terminator after the last non-whitespace character. This prevents excessive trailing line breaks. */
            for (size_t i = 0, i_last = 0;; i++)
            {
                if (szErrMessage[i])
                {
                    if (!_istspace(szErrMessage[i]))
                    {
                        i_last = i + 1;
                    }
                }
                else
                {
                    szErrMessage[i_last] = 0;
                    break;
                }
            }
            MsiRecordSetString(hRecordProg, 4, szErrMessage);
            LocalFree(szErrMessage);
        }
    }

    MsiProcessMessage(s->hInstall, (flags & M_WARN) ? INSTALLMESSAGE_INFO : INSTALLMESSAGE_ERROR, hRecordProg);
    MsiCloseHandle(hRecordProg);
}
