/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
 *
 *  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.
 */

/*
 * Win32-specific OpenVPN code, targeted at the mingw
 * development environment.
 */

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

#include "syshead.h"

#ifdef _WIN32

#include "buffer.h"
#include "error.h"
#include "mtu.h"
#include "run_command.h"
#include "sig.h"
#include "win32.h"
#include "openvpn-msg.h"

#include "memdbg.h"

#ifdef HAVE_VERSIONHELPERS_H
#include <versionhelpers.h>
#else
#include "compat-versionhelpers.h"
#endif

#include "block_dns.h"

/*
 * WFP handle
 */
static HANDLE m_hEngineHandle = NULL; /* GLOBAL */

/*
 * TAP adapter original metric value
 */
static int tap_metric_v4 = -1; /* GLOBAL */
static int tap_metric_v6 = -1; /* GLOBAL */

/*
 * Windows internal socket API state (opaque).
 */
static struct WSAData wsa_state; /* GLOBAL */

/*
 * Should we call win32_pause() on program exit?
 */
static bool pause_exit_enabled = false; /* GLOBAL */

/*
 * win32_signal is used to get input from the keyboard
 * if we are running in a console, or get input from an
 * event object if we are running as a service.
 */

struct win32_signal win32_signal; /* GLOBAL */

/*
 * Save our old window title so we can restore
 * it on exit.
 */
struct window_title window_title; /* GLOBAL*/

/*
 * Special global semaphore used to protect network
 * shell commands from simultaneous instantiation.
 */

struct semaphore netcmd_semaphore; /* GLOBAL */

/*
 * Windows system pathname such as c:\windows
 */
static char *win_sys_path = NULL; /* GLOBAL */

void
init_win32(void)
{
    if (WSAStartup(0x0101, &wsa_state))
    {
        msg(M_ERR, "WSAStartup failed");
    }
    window_title_clear(&window_title);
    win32_signal_clear(&win32_signal);
}

void
uninit_win32(void)
{
    netcmd_semaphore_close();
    if (pause_exit_enabled)
    {
        if (win32_signal.mode == WSO_MODE_UNDEF)
        {
            struct win32_signal w;
            win32_signal_open(&w, WSO_FORCE_CONSOLE, NULL, false);
            win32_pause(&w);
            win32_signal_close(&w);
        }
        else
        {
            win32_pause(&win32_signal);
        }
    }
    window_title_restore(&window_title);
    win32_signal_close(&win32_signal);
    WSACleanup();
    free(win_sys_path);
}

void
set_pause_exit_win32(void)
{
    pause_exit_enabled = true;
}

bool
init_security_attributes_allow_all(struct security_attributes *obj)
{
    CLEAR(*obj);

    obj->sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    obj->sa.lpSecurityDescriptor = &obj->sd;
    obj->sa.bInheritHandle = FALSE;
    if (!InitializeSecurityDescriptor(&obj->sd, SECURITY_DESCRIPTOR_REVISION))
    {
        return false;
    }
    if (!SetSecurityDescriptorDacl(&obj->sd, TRUE, NULL, FALSE))
    {
        return false;
    }
    return true;
}

void
overlapped_io_init(struct overlapped_io *o,
                   const struct frame *frame,
                   BOOL event_state,
                   bool tuntap_buffer)  /* if true: tuntap buffer, if false: socket buffer */
{
    CLEAR(*o);

    /* manual reset event, initially set according to event_state */
    o->overlapped.hEvent = CreateEvent(NULL, TRUE, event_state, NULL);
    if (o->overlapped.hEvent == NULL)
    {
        msg(M_ERR, "Error: overlapped_io_init: CreateEvent failed");
    }

    /* allocate buffer for overlapped I/O */
    alloc_buf_sock_tun(&o->buf_init, frame, tuntap_buffer, 0);
}

void
overlapped_io_close(struct overlapped_io *o)
{
    if (o->overlapped.hEvent)
    {
        if (!CloseHandle(o->overlapped.hEvent))
        {
            msg(M_WARN | M_ERRNO, "Warning: CloseHandle failed on overlapped I/O event object");
        }
    }
    free_buf(&o->buf_init);
}

char *
overlapped_io_state_ascii(const struct overlapped_io *o)
{
    switch (o->iostate)
    {
        case IOSTATE_INITIAL:
            return "0";

        case IOSTATE_QUEUED:
            return "Q";

        case IOSTATE_IMMEDIATE_RETURN:
            return "1";
    }
    return "?";
}

/*
 * Event-based notification of network events
 */

void
init_net_event_win32(struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags)
{
    /* manual reset events, initially set to unsignaled */

    /* initialize write event */
    if (!(flags & NE32_PERSIST_EVENT) || !event->write)
    {
        if (flags & NE32_WRITE_EVENT)
        {
            event->write = CreateEvent(NULL, TRUE, FALSE, NULL);
            if (event->write == NULL)
            {
                msg(M_ERR, "Error: init_net_event_win32: CreateEvent (write) failed");
            }
        }
        else
        {
            event->write = NULL;
        }
    }

    /* initialize read event */
    if (!(flags & NE32_PERSIST_EVENT) || !event->read)
    {
        event->read = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (event->read == NULL)
        {
            msg(M_ERR, "Error: init_net_event_win32: CreateEvent (read) failed");
        }
    }

    /* setup network events to change read event state */
    if (WSAEventSelect(sd, event->read, network_events) != 0)
    {
        msg(M_FATAL | M_ERRNO, "Error: init_net_event_win32: WSAEventSelect call failed");
    }
}

long
reset_net_event_win32(struct rw_handle *event, socket_descriptor_t sd)
{
    WSANETWORKEVENTS wne;
    if (WSAEnumNetworkEvents(sd, event->read, &wne) != 0)
    {
        msg(M_FATAL | M_ERRNO, "Error: reset_net_event_win32: WSAEnumNetworkEvents call failed");
        return 0; /* NOTREACHED */
    }
    else
    {
        return wne.lNetworkEvents;
    }
}

void
close_net_event_win32(struct rw_handle *event, socket_descriptor_t sd, unsigned int flags)
{
    if (event->read)
    {
        if (socket_defined(sd))
        {
            if (WSAEventSelect(sd, event->read, 0) != 0)
            {
                msg(M_WARN | M_ERRNO, "Warning: close_net_event_win32: WSAEventSelect call failed");
            }
        }
        if (!ResetEvent(event->read))
        {
            msg(M_WARN | M_ERRNO, "Warning: ResetEvent (read) failed in close_net_event_win32");
        }
        if (!(flags & NE32_PERSIST_EVENT))
        {
            if (!CloseHandle(event->read))
            {
                msg(M_WARN | M_ERRNO, "Warning: CloseHandle (read) failed in close_net_event_win32");
            }
            event->read = NULL;
        }
    }

    if (event->write)
    {
        if (!ResetEvent(event->write))
        {
            msg(M_WARN | M_ERRNO, "Warning: ResetEvent (write) failed in close_net_event_win32");
        }
        if (!(flags & NE32_PERSIST_EVENT))
        {
            if (!CloseHandle(event->write))
            {
                msg(M_WARN | M_ERRNO, "Warning: CloseHandle (write) failed in close_net_event_win32");
            }
            event->write = NULL;
        }
    }
}

/*
 * struct net_event_win32
 */

void
net_event_win32_init(struct net_event_win32 *ne)
{
    CLEAR(*ne);
    ne->sd = SOCKET_UNDEFINED;
}

void
net_event_win32_start(struct net_event_win32 *ne, long network_events, socket_descriptor_t sd)
{
    ASSERT(!socket_defined(ne->sd));
    ne->sd = sd;
    ne->event_mask = 0;
    init_net_event_win32(&ne->handle, network_events, sd, NE32_PERSIST_EVENT|NE32_WRITE_EVENT);
}

void
net_event_win32_reset_write(struct net_event_win32 *ne)
{
    BOOL status;
    if (ne->event_mask & FD_WRITE)
    {
        status = SetEvent(ne->handle.write);
    }
    else
    {
        status = ResetEvent(ne->handle.write);
    }
    if (!status)
    {
        msg(M_WARN | M_ERRNO, "Warning: SetEvent/ResetEvent failed in net_event_win32_reset_write");
    }
}

void
net_event_win32_reset(struct net_event_win32 *ne)
{
    ne->event_mask |= reset_net_event_win32(&ne->handle, ne->sd);
}

void
net_event_win32_stop(struct net_event_win32 *ne)
{
    if (net_event_win32_defined(ne))
    {
        close_net_event_win32(&ne->handle, ne->sd, NE32_PERSIST_EVENT);
    }
    ne->sd = SOCKET_UNDEFINED;
    ne->event_mask = 0;
}

void
net_event_win32_close(struct net_event_win32 *ne)
{
    if (net_event_win32_defined(ne))
    {
        close_net_event_win32(&ne->handle, ne->sd, 0);
    }
    net_event_win32_init(ne);
}

/*
 * Simulate *nix signals on Windows.
 *
 * Two modes:
 * (1) Console mode -- map keyboard function keys to signals
 * (2) Service mode -- map Windows event object to SIGTERM
 */

static void
win_trigger_event(struct win32_signal *ws)
{
    if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED(ws->in.read))
    {
        SetEvent(ws->in.read);
    }
    else /* generate a key-press event */
    {
        DWORD tmp;
        INPUT_RECORD ir;
        HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);

        CLEAR(ir);
        ir.EventType = KEY_EVENT;
        ir.Event.KeyEvent.bKeyDown = true;
        if (!stdin_handle || !WriteConsoleInput(stdin_handle, &ir, 1, &tmp))
        {
            msg(M_WARN|M_ERRNO, "WARN: win_trigger_event: WriteConsoleInput");
        }
    }
}

/*
 * Callback to handle console ctrl events
 */
static bool WINAPI
win_ctrl_handler(DWORD signum)
{
    msg(D_LOW, "win_ctrl_handler: signal received (code=%lu)", (unsigned long) signum);

    if (siginfo_static.signal_received == SIGTERM)
    {
        return true;
    }

    switch (signum)
    {
        case CTRL_C_EVENT:
        case CTRL_BREAK_EVENT:
            throw_signal(SIGTERM);
            /* trigget the win32_signal to interrupt the event loop */
            win_trigger_event(&win32_signal);
            return true;
            break;

        default:
            msg(D_LOW, "win_ctrl_handler: signal (code=%lu) not handled", (unsigned long) signum);
            break;
    }
    /* pass all other signals to the next handler */
    return false;
}

void
win32_signal_clear(struct win32_signal *ws)
{
    CLEAR(*ws);
}

void
win32_signal_open(struct win32_signal *ws,
                  int force,
                  const char *exit_event_name,
                  bool exit_event_initial_state)
{
    CLEAR(*ws);

    ws->mode = WSO_MODE_UNDEF;
    ws->in.read = INVALID_HANDLE_VALUE;
    ws->in.write = INVALID_HANDLE_VALUE;
    ws->console_mode_save = 0;
    ws->console_mode_save_defined = false;

    if (force == WSO_NOFORCE || force == WSO_FORCE_CONSOLE)
    {
        /*
         * Try to open console.
         */
        ws->in.read = GetStdHandle(STD_INPUT_HANDLE);
        if (ws->in.read != INVALID_HANDLE_VALUE)
        {
            if (GetConsoleMode(ws->in.read, &ws->console_mode_save))
            {
                /* running on a console */
                const DWORD new_console_mode = ws->console_mode_save
                                               & ~(ENABLE_WINDOW_INPUT
                                                   | ENABLE_PROCESSED_INPUT
                                                   | ENABLE_LINE_INPUT
                                                   | ENABLE_ECHO_INPUT
                                                   | ENABLE_MOUSE_INPUT);

                if (new_console_mode != ws->console_mode_save)
                {
                    if (!SetConsoleMode(ws->in.read, new_console_mode))
                    {
                        msg(M_ERR, "Error: win32_signal_open: SetConsoleMode failed");
                    }
                    ws->console_mode_save_defined = true;
                }
                ws->mode = WSO_MODE_CONSOLE;
            }
            else
            {
                ws->in.read = INVALID_HANDLE_VALUE; /* probably running as a service */
            }
        }
    }

    /*
     * If console open failed, assume we are running
     * as a service.
     */
    if ((force == WSO_NOFORCE || force == WSO_FORCE_SERVICE)
        && !HANDLE_DEFINED(ws->in.read) && exit_event_name)
    {
        struct security_attributes sa;

        if (!init_security_attributes_allow_all(&sa))
        {
            msg(M_ERR, "Error: win32_signal_open: init SA failed");
        }

        ws->in.read = CreateEvent(&sa.sa,
                                  TRUE,
                                  exit_event_initial_state ? TRUE : FALSE,
                                  exit_event_name);
        if (ws->in.read == NULL)
        {
            msg(M_WARN|M_ERRNO, "NOTE: CreateEvent '%s' failed", exit_event_name);
        }
        else
        {
            if (WaitForSingleObject(ws->in.read, 0) != WAIT_TIMEOUT)
            {
                msg(M_FATAL, "ERROR: Exit Event ('%s') is signaled", exit_event_name);
            }
            else
            {
                ws->mode = WSO_MODE_SERVICE;
            }
        }
    }
    /* set the ctrl handler in both console and service modes */
    if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) win_ctrl_handler, true))
    {
        msg(M_WARN|M_ERRNO, "WARN: SetConsoleCtrlHandler failed");
    }
}

static bool
keyboard_input_available(struct win32_signal *ws)
{
    ASSERT(ws->mode == WSO_MODE_CONSOLE);
    if (HANDLE_DEFINED(ws->in.read))
    {
        DWORD n;
        if (GetNumberOfConsoleInputEvents(ws->in.read, &n))
        {
            return n > 0;
        }
    }
    return false;
}

static unsigned int
keyboard_ir_to_key(INPUT_RECORD *ir)
{
    if (ir->Event.KeyEvent.uChar.AsciiChar == 0)
    {
        return ir->Event.KeyEvent.wVirtualScanCode;
    }

    if ((ir->Event.KeyEvent.dwControlKeyState
         & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
        && (ir->Event.KeyEvent.wVirtualKeyCode != 18))
    {
        return ir->Event.KeyEvent.wVirtualScanCode * 256;
    }

    return ir->Event.KeyEvent.uChar.AsciiChar;
}

static unsigned int
win32_keyboard_get(struct win32_signal *ws)
{
    ASSERT(ws->mode == WSO_MODE_CONSOLE);
    if (HANDLE_DEFINED(ws->in.read))
    {
        INPUT_RECORD ir;
        do
        {
            DWORD n;
            if (!keyboard_input_available(ws))
            {
                return 0;
            }
            if (!ReadConsoleInput(ws->in.read, &ir, 1, &n))
            {
                return 0;
            }
        } while (ir.EventType != KEY_EVENT || ir.Event.KeyEvent.bKeyDown != TRUE);

        return keyboard_ir_to_key(&ir);
    }
    else
    {
        return 0;
    }
}

void
win32_signal_close(struct win32_signal *ws)
{
    if (ws->mode == WSO_MODE_SERVICE && HANDLE_DEFINED(ws->in.read))
    {
        CloseHandle(ws->in.read);
    }
    if (ws->console_mode_save_defined)
    {
        if (!SetConsoleMode(ws->in.read, ws->console_mode_save))
        {
            msg(M_ERR, "Error: win32_signal_close: SetConsoleMode failed");
        }
    }
    CLEAR(*ws);
}

/*
 * Return true if interrupt occurs in service mode.
 */
bool
win32_service_interrupt(struct win32_signal *ws)
{
    if (ws->mode == WSO_MODE_SERVICE)
    {
        if (HANDLE_DEFINED(ws->in.read)
            && WaitForSingleObject(ws->in.read, 0) == WAIT_OBJECT_0)
        {
            return true;
        }
    }
    return false;
}

int
win32_signal_get(struct win32_signal *ws)
{
    int ret = 0;
    if (siginfo_static.signal_received)
    {
        ret = siginfo_static.signal_received;
    }
    else
    {
        if (ws->mode == WSO_MODE_SERVICE)
        {
            if (win32_service_interrupt(ws))
            {
                ret = SIGTERM;
            }
        }
        else if (ws->mode == WSO_MODE_CONSOLE)
        {
            switch (win32_keyboard_get(ws))
            {
                case 0x3B: /* F1 -> USR1 */
                    ret = SIGUSR1;
                    break;

                case 0x3C: /* F2 -> USR2 */
                    ret = SIGUSR2;
                    break;

                case 0x3D: /* F3 -> HUP */
                    ret = SIGHUP;
                    break;

                case 0x3E: /* F4 -> TERM */
                    ret = SIGTERM;
                    break;

                case 0x03: /* CTRL-C -> TERM */
                    ret = SIGTERM;
                    break;
            }
        }
        if (ret)
        {
            siginfo_static.signal_received = ret;
            siginfo_static.source = SIG_SOURCE_HARD;
        }
    }
    return ret;
}

void
win32_pause(struct win32_signal *ws)
{
    if (ws->mode == WSO_MODE_CONSOLE && HANDLE_DEFINED(ws->in.read))
    {
        msg(M_INFO|M_NOPREFIX, "Press any key to continue...");
        do
        {
            WaitForSingleObject(ws->in.read, INFINITE);
        } while (!win32_keyboard_get(ws));
    }
}

/* window functions */

void
window_title_clear(struct window_title *wt)
{
    CLEAR(*wt);
}

void
window_title_save(struct window_title *wt)
{
    if (!wt->saved)
    {
        if (!GetConsoleTitle(wt->old_window_title, sizeof(wt->old_window_title)))
        {
            wt->old_window_title[0] = 0;
            wt->saved = false;
        }
        else
        {
            wt->saved = true;
        }
    }
}

void
window_title_restore(const struct window_title *wt)
{
    if (wt->saved)
    {
        SetConsoleTitle(wt->old_window_title);
    }
}

void
window_title_generate(const char *title)
{
    struct gc_arena gc = gc_new();
    struct buffer out = alloc_buf_gc(256, &gc);
    if (!title)
    {
        title = "";
    }
    buf_printf(&out, "[%s] " PACKAGE_NAME " " PACKAGE_VERSION " F4:EXIT F1:USR1 F2:USR2 F3:HUP", title);
    SetConsoleTitle(BSTR(&out));
    gc_free(&gc);
}

/* semaphore functions */

void
semaphore_clear(struct semaphore *s)
{
    CLEAR(*s);
}

void
semaphore_open(struct semaphore *s, const char *name)
{
    struct security_attributes sa;

    s->locked = false;
    s->name = name;
    s->hand = NULL;

    if (init_security_attributes_allow_all(&sa))
    {
        s->hand = CreateSemaphore(&sa.sa, 1, 1, name);
    }

    if (s->hand == NULL)
    {
        msg(M_WARN|M_ERRNO, "WARNING: Cannot create Win32 semaphore '%s'", name);
    }
    else
    {
        dmsg(D_SEMAPHORE, "Created Win32 semaphore '%s'", s->name);
    }
}

bool
semaphore_lock(struct semaphore *s, int timeout_milliseconds)
{
    bool ret = true;

    if (s->hand)
    {
        DWORD status;
        ASSERT(!s->locked);

        dmsg(D_SEMAPHORE_LOW, "Attempting to lock Win32 semaphore '%s' prior to net shell command (timeout = %d sec)",
             s->name,
             timeout_milliseconds / 1000);
        status = WaitForSingleObject(s->hand, timeout_milliseconds);
        if (status == WAIT_FAILED)
        {
            msg(M_ERR, "Wait failed on Win32 semaphore '%s'", s->name);
        }
        ret = (status == WAIT_TIMEOUT) ? false : true;
        if (ret)
        {
            dmsg(D_SEMAPHORE, "Locked Win32 semaphore '%s'", s->name);
            s->locked = true;
        }
        else
        {
            dmsg(D_SEMAPHORE, "Wait on Win32 semaphore '%s' timed out after %d milliseconds",
                 s->name,
                 timeout_milliseconds);
        }
    }
    return ret;
}

void
semaphore_release(struct semaphore *s)
{
    if (s->hand)
    {
        ASSERT(s->locked);
        dmsg(D_SEMAPHORE, "Releasing Win32 semaphore '%s'", s->name);
        if (!ReleaseSemaphore(s->hand, 1, NULL))
        {
            msg(M_WARN | M_ERRNO, "ReleaseSemaphore failed on Win32 semaphore '%s'",
                s->name);
        }
        s->locked = false;
    }
}

void
semaphore_close(struct semaphore *s)
{
    if (s->hand)
    {
        if (s->locked)
        {
            semaphore_release(s);
        }
        dmsg(D_SEMAPHORE, "Closing Win32 semaphore '%s'", s->name);
        CloseHandle(s->hand);
        s->hand = NULL;
    }
}

/*
 * Special global semaphore used to protect network
 * shell commands from simultaneous instantiation.
 */

void
netcmd_semaphore_init(void)
{
    semaphore_open(&netcmd_semaphore, PACKAGE "_netcmd");
}

void
netcmd_semaphore_close(void)
{
    semaphore_close(&netcmd_semaphore);
}

void
netcmd_semaphore_lock(void)
{
    const int timeout_seconds = 600;

    if (!netcmd_semaphore.hand)
    {
        netcmd_semaphore_init();
    }

    if (!semaphore_lock(&netcmd_semaphore, timeout_seconds * 1000))
    {
        msg(M_FATAL, "Cannot lock net command semaphore");
    }
}

void
netcmd_semaphore_release(void)
{
    semaphore_release(&netcmd_semaphore);
    /* netcmd_semaphore has max count of 1 - safe to close after release */
    semaphore_close(&netcmd_semaphore);
}

/*
 * Return true if filename is safe to be used on Windows,
 * by avoiding the following reserved names:
 *
 * CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9,
 * LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, and CLOCK$
 *
 * See: http://msdn.microsoft.com/en-us/library/aa365247.aspx
 *  and http://msdn.microsoft.com/en-us/library/86k9f82k(VS.80).aspx
 */

static bool
cmp_prefix(const char *str, const bool n, const char *pre)
{
    size_t i = 0;

    if (!str)
    {
        return false;
    }

    while (true)
    {
        const int c1 = pre[i];
        int c2 = str[i];
        ++i;
        if (c1 == '\0')
        {
            if (n)
            {
                if (isdigit(c2))
                {
                    c2 = str[i];
                }
                else
                {
                    return false;
                }
            }
            return c2 == '\0' || c2 == '.';
        }
        else if (c2 == '\0')
        {
            return false;
        }
        if (c1 != tolower(c2))
        {
            return false;
        }
    }
}

bool
win_safe_filename(const char *fn)
{
    if (cmp_prefix(fn, false, "con"))
    {
        return false;
    }
    if (cmp_prefix(fn, false, "prn"))
    {
        return false;
    }
    if (cmp_prefix(fn, false, "aux"))
    {
        return false;
    }
    if (cmp_prefix(fn, false, "nul"))
    {
        return false;
    }
    if (cmp_prefix(fn, true, "com"))
    {
        return false;
    }
    if (cmp_prefix(fn, true, "lpt"))
    {
        return false;
    }
    if (cmp_prefix(fn, false, "clock$"))
    {
        return false;
    }
    return true;
}

/*
 * Service functions for openvpn_execve
 */

static char *
env_block(const struct env_set *es)
{
    char force_path[256];
    char *sysroot = get_win_sys_path();

    if (!openvpn_snprintf(force_path, sizeof(force_path), "PATH=%s\\System32;%s;%s\\System32\\Wbem",
                          sysroot, sysroot, sysroot))
    {
        msg(M_WARN, "env_block: default path truncated to %s", force_path);
    }

    if (es)
    {
        struct env_item *e;
        char *ret;
        char *p;
        size_t nchars = 1;
        bool path_seen = false;

        for (e = es->list; e != NULL; e = e->next)
        {
            nchars += strlen(e->string) + 1;
        }

        nchars += strlen(force_path)+1;

        ret = (char *) malloc(nchars);
        check_malloc_return(ret);

        p = ret;
        for (e = es->list; e != NULL; e = e->next)
        {
            if (env_allowed(e->string))
            {
                strcpy(p, e->string);
                p += strlen(e->string) + 1;
            }
            if (strncmp(e->string, "PATH=", 5 ) == 0)
            {
                path_seen = true;
            }
        }

        /* make sure PATH is set */
        if (!path_seen)
        {
            msg( M_INFO, "env_block: add %s", force_path );
            strcpy( p, force_path );
            p += strlen(force_path) + 1;
        }

        *p = '\0';
        return ret;
    }
    else
    {
        return NULL;
    }
}

static WCHAR *
wide_cmd_line(const struct argv *a, struct gc_arena *gc)
{
    size_t nchars = 1;
    size_t maxlen = 0;
    size_t i;
    struct buffer buf;
    char *work = NULL;

    if (!a)
    {
        return NULL;
    }

    for (i = 0; i < a->argc; ++i)
    {
        const char *arg = a->argv[i];
        const size_t len = strlen(arg);
        nchars += len + 3;
        if (len > maxlen)
        {
            maxlen = len;
        }
    }

    work = gc_malloc(maxlen + 1, false, gc);
    check_malloc_return(work);
    buf = alloc_buf_gc(nchars, gc);

    for (i = 0; i < a->argc; ++i)
    {
        const char *arg = a->argv[i];
        strcpy(work, arg);
        string_mod(work, CC_PRINT, CC_DOUBLE_QUOTE|CC_CRLF, '_');
        if (i)
        {
            buf_printf(&buf, " ");
        }
        if (string_class(work, CC_ANY, CC_SPACE))
        {
            buf_printf(&buf, "%s", work);
        }
        else
        {
            buf_printf(&buf, "\"%s\"", work);
        }
    }

    return wide_string(BSTR(&buf), gc);
}

/*
 * Attempt to simulate fork/execve on Windows
 */
int
openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
{
    int ret = OPENVPN_EXECVE_ERROR;
    static bool exec_warn = false;

    if (a && a->argv[0])
    {
        if (openvpn_execve_allowed(flags))
        {
            struct gc_arena gc = gc_new();
            STARTUPINFOW start_info;
            PROCESS_INFORMATION proc_info;

            char *env = env_block(es);
            WCHAR *cl = wide_cmd_line(a, &gc);
            WCHAR *cmd = wide_string(a->argv[0], &gc);

            /* this allows console programs to run, and is ignored otherwise */
            DWORD proc_flags = CREATE_NO_WINDOW;

            CLEAR(start_info);
            CLEAR(proc_info);

            /* fill in STARTUPINFO struct */
            GetStartupInfoW(&start_info);
            start_info.cb = sizeof(start_info);
            start_info.dwFlags = STARTF_USESHOWWINDOW;
            start_info.wShowWindow = SW_HIDE;

            if (CreateProcessW(cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
            {
                DWORD exit_status = 0;
                CloseHandle(proc_info.hThread);
                WaitForSingleObject(proc_info.hProcess, INFINITE);
                if (GetExitCodeProcess(proc_info.hProcess, &exit_status))
                {
                    ret = (int)exit_status;
                }
                else
                {
                    msg(M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %S failed", cmd);
                }
                CloseHandle(proc_info.hProcess);
            }
            else
            {
                msg(M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %S failed", cmd);
            }
            free(env);
            gc_free(&gc);
        }
        else
        {
            ret = OPENVPN_EXECVE_NOT_ALLOWED;
            if (!exec_warn && (script_security() < SSEC_SCRIPTS))
            {
                msg(M_WARN, SCRIPT_SECURITY_WARNING);
                exec_warn = true;
            }
        }
    }
    else
    {
        msg(M_WARN, "openvpn_execve: called with empty argv");
    }
    return ret;
}

WCHAR *
wide_string(const char *utf8, struct gc_arena *gc)
{
    int n = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
    WCHAR *ucs16 = gc_malloc(n * sizeof(WCHAR), false, gc);
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ucs16, n);
    return ucs16;
}

/*
 * call ourself in another process
 */
void
fork_to_self(const char *cmdline)
{
    STARTUPINFO start_info;
    PROCESS_INFORMATION proc_info;
    char self_exe[256];
    char *cl = string_alloc(cmdline, NULL);
    DWORD status;

    CLEAR(start_info);
    CLEAR(proc_info);
    CLEAR(self_exe);

    status = GetModuleFileName(NULL, self_exe, sizeof(self_exe));
    if (status == 0 || status == sizeof(self_exe))
    {
        msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: cannot get module name via GetModuleFileName");
        goto done;
    }

    /* fill in STARTUPINFO struct */
    GetStartupInfo(&start_info);
    start_info.cb = sizeof(start_info);
    start_info.dwFlags = STARTF_USESHOWWINDOW;
    start_info.wShowWindow = SW_HIDE;

    if (CreateProcess(self_exe, cl, NULL, NULL, FALSE, 0, NULL, NULL, &start_info, &proc_info))
    {
        CloseHandle(proc_info.hThread);
        CloseHandle(proc_info.hProcess);
    }
    else
    {
        msg(M_WARN|M_ERRNO, "fork_to_self: CreateProcess failed: %s", cmdline);
    }

done:
    free(cl);
}

char *
get_win_sys_path(void)
{
    ASSERT(win_sys_path);
    return win_sys_path;
}

void
set_win_sys_path(const char *newpath, struct env_set *es)
{
    free(win_sys_path);
    win_sys_path = string_alloc(newpath, NULL);
    setenv_str(es, SYS_PATH_ENV_VAR_NAME, win_sys_path); /* route.exe needs this */
}

void
set_win_sys_path_via_env(struct env_set *es)
{
    char buf[256];
    DWORD status = GetEnvironmentVariable(SYS_PATH_ENV_VAR_NAME, buf, sizeof(buf));
    if (!status)
    {
        msg(M_ERR, "Cannot find environmental variable %s", SYS_PATH_ENV_VAR_NAME);
    }
    if (status > sizeof(buf) - 1)
    {
        msg(M_FATAL, "String overflow attempting to read environmental variable %s", SYS_PATH_ENV_VAR_NAME);
    }
    set_win_sys_path(buf, es);
}


const char *
win_get_tempdir(void)
{
    static char tmpdir[MAX_PATH];
    WCHAR wtmpdir[MAX_PATH];

    if (!GetTempPathW(_countof(wtmpdir), wtmpdir))
    {
        /* Warn if we can't find a valid temporary directory, which should
         * be unlikely.
         */
        msg(M_WARN, "Could not find a suitable temporary directory."
            " (GetTempPath() failed).  Consider using --tmp-dir");
        return NULL;
    }

    if (WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, NULL, 0, NULL, NULL) > sizeof(tmpdir))
    {
        msg(M_WARN, "Could not get temporary directory. Path is too long."
            "  Consider using --tmp-dir");
        return NULL;
    }

    WideCharToMultiByte(CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof(tmpdir), NULL, NULL);
    return tmpdir;
}

static bool
win_block_dns_service(bool add, int index, const HANDLE pipe)
{
    bool ret = false;
    ack_message_t ack;
    struct gc_arena gc = gc_new();

    block_dns_message_t data = {
        .header = {
            (add ? msg_add_block_dns : msg_del_block_dns),
            sizeof(block_dns_message_t),
            0
        },
        .iface = { .index = index, .name = "" }
    };

    if (!send_msg_iservice(pipe, &data, sizeof(data), &ack, "Block_DNS"))
    {
        goto out;
    }

    if (ack.error_number != NO_ERROR)
    {
        msg(M_WARN, "Block_DNS: %s block dns filters using service failed: %s [status=0x%x if_index=%d]",
            (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
            ack.error_number, data.iface.index);
        goto out;
    }

    ret = true;
    msg(M_INFO, "%s outside dns using service succeeded.", (add ? "Blocking" : "Unblocking"));
out:
    gc_free(&gc);
    return ret;
}

static void
block_dns_msg_handler(DWORD err, const char *msg)
{
    struct gc_arena gc = gc_new();

    if (err == 0)
    {
        msg(M_INFO, "%s", msg);
    }
    else
    {
        msg(M_WARN, "Error in add_block_dns_filters(): %s : %s [status=0x%lx]",
            msg, strerror_win32(err, &gc), err);
    }

    gc_free(&gc);
}

bool
win_wfp_block_dns(const NET_IFINDEX index, const HANDLE msg_channel)
{
    WCHAR openvpnpath[MAX_PATH];
    bool ret = false;
    DWORD status;

    if (msg_channel)
    {
        dmsg(D_LOW, "Using service to add block dns filters");
        ret = win_block_dns_service(true, index, msg_channel);
        goto out;
    }

    status = GetModuleFileNameW(NULL, openvpnpath, _countof(openvpnpath));
    if (status == 0 || status == _countof(openvpnpath))
    {
        msg(M_WARN|M_ERRNO, "block_dns: cannot get executable path");
        goto out;
    }

    status = add_block_dns_filters(&m_hEngineHandle, index, openvpnpath,
                                   block_dns_msg_handler);
    if (status == 0)
    {
        int is_auto = 0;
        tap_metric_v4 = get_interface_metric(index, AF_INET, &is_auto);
        if (is_auto)
        {
            tap_metric_v4 = 0;
        }
        tap_metric_v6 = get_interface_metric(index, AF_INET6, &is_auto);
        if (is_auto)
        {
            tap_metric_v6 = 0;
        }
        status = set_interface_metric(index, AF_INET, BLOCK_DNS_IFACE_METRIC);
        if (!status)
        {
            set_interface_metric(index, AF_INET6, BLOCK_DNS_IFACE_METRIC);
        }
    }

    ret = (status == 0);

out:

    return ret;
}

bool
win_wfp_uninit(const NET_IFINDEX index, const HANDLE msg_channel)
{
    dmsg(D_LOW, "Uninitializing WFP");

    if (msg_channel)
    {
        msg(D_LOW, "Using service to delete block dns filters");
        win_block_dns_service(false, index, msg_channel);
    }
    else
    {
        delete_block_dns_filters(m_hEngineHandle);
        m_hEngineHandle = NULL;
        if (tap_metric_v4 >= 0)
        {
            set_interface_metric(index, AF_INET, tap_metric_v4);
        }
        if (tap_metric_v6 >= 0)
        {
            set_interface_metric(index, AF_INET6, tap_metric_v6);
        }
    }

    return true;
}

int
win32_version_info(void)
{
    if (!IsWindowsXPOrGreater())
    {
        msg(M_FATAL, "Error: Windows version must be XP or greater.");
    }

    if (!IsWindowsVistaOrGreater())
    {
        return WIN_XP;
    }

    if (!IsWindows7OrGreater())
    {
        return WIN_VISTA;
    }

    if (!IsWindows8OrGreater())
    {
        return WIN_7;
    }

    if (!IsWindows8Point1OrGreater())
    {
        return WIN_8;
    }

    if (!IsWindows10OrGreater())
    {
        return WIN_8_1;
    }

    return WIN_10;
}

bool
win32_is_64bit(void)
{
#if defined(_WIN64)
    return true;  /* 64-bit programs run only on Win64 */
#elif defined(_WIN32)
    /* 32-bit programs run on both 32-bit and 64-bit Windows */
    BOOL f64 = FALSE;
    return IsWow64Process(GetCurrentProcess(), &f64) && f64;
#else  /* if defined(_WIN64) */
    return false; /* Win64 does not support Win16 */
#endif
}

const char *
win32_version_string(struct gc_arena *gc, bool add_name)
{
    int version = win32_version_info();
    struct buffer out = alloc_buf_gc(256, gc);

    switch (version)
    {
        case WIN_XP:
            buf_printf(&out, "5.1%s", add_name ? " (Windows XP)" : "");
            break;

        case WIN_VISTA:
            buf_printf(&out, "6.0%s", add_name ? " (Windows Vista)" : "");
            break;

        case WIN_7:
            buf_printf(&out, "6.1%s", add_name ? " (Windows 7)" : "");
            break;

        case WIN_8:
            buf_printf(&out, "6.2%s", add_name ? " (Windows 8)" : "");
            break;

        case WIN_8_1:
            buf_printf(&out, "6.3%s", add_name ? " (Windows 8.1)" : "");
            break;

        case WIN_10:
            buf_printf(&out, "10.0%s", add_name ? " (Windows 10 or greater)" : "");
            break;

        default:
            msg(M_NONFATAL, "Unknown Windows version: %d", version);
            buf_printf(&out, "0.0%s", add_name ? " (unknown)" : "");
            break;
    }

    buf_printf(&out, win32_is_64bit() ? " 64bit" : " 32bit");

    return (const char *)out.data;
}

bool
send_msg_iservice(HANDLE pipe, const void *data, size_t size,
                  ack_message_t *ack, const char *context)
{
    struct gc_arena gc = gc_new();
    DWORD len;
    bool ret = true;

    if (!WriteFile(pipe, data, size, &len, NULL)
        || !ReadFile(pipe, ack, sizeof(*ack), &len, NULL))
    {
        msg(M_WARN, "%s: could not talk to service: %s [%lu]",
            context ? context : "Unknown",
            strerror_win32(GetLastError(), &gc), GetLastError());
        ret = false;
    }

    gc_free(&gc);
    return ret;
}

#endif /* ifdef _WIN32 */
