/*
 *   stunnel       TLS offloading and load-balancing proxy
 *   Copyright (C) 1998-2015 Michal Trojnara <Michal.Trojnara@mirt.net>
 *
 *   This program is free software; you can redistribute it and/or modify it
 *   under the terms of the GNU General Public License as published by the
 *   Free Software Foundation; either version 2 of the License, or (at your
 *   option) any later version.
 *
 *   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, see <http://www.gnu.org/licenses>.
 *
 *   Linking stunnel statically or dynamically with other modules is making
 *   a combined work based on stunnel. Thus, the terms and conditions of
 *   the GNU General Public License cover the whole combination.
 *
 *   In addition, as a special exception, the copyright holder of stunnel
 *   gives you permission to combine stunnel with free software programs or
 *   libraries that are released under the GNU LGPL and with code included
 *   in the standard release of OpenSSL under the OpenSSL License (or
 *   modified versions of such code, with unchanged license). You may copy
 *   and distribute such a system following the terms of the GNU GPL for
 *   stunnel and the licenses of the other code concerned.
 *
 *   Note that people who make modified versions of stunnel are not obligated
 *   to grant this special exception for their modified versions; it is their
 *   choice whether to do so. The GNU General Public License gives permission
 *   to release a modified version without this exception; this exception
 *   also makes it possible to release a modified version which carries
 *   forward this exception.
 */

#include "common.h"
#include "prototypes.h"
#include <commdlg.h>
#include <commctrl.h>
#ifndef _WIN32_WCE
#include <psapi.h>
#endif
#include "resources.h"

#define LOG_LINES 1000

#ifdef _WIN32_WCE
#define STUNNEL_PLATFORM "WinCE"
#else
#ifdef _WIN64
#define STUNNEL_PLATFORM "Win64"
#else /* MSDN claims that _WIN32 is always defined */
#define STUNNEL_PLATFORM "Win32"
#endif
#define SERVICE_NAME TEXT("stunnel")
#define SERVICE_DISPLAY_NAME TEXT("Stunnel SSL wrapper")
#endif

/* mingw-Patches-1825044 is missing in Debian Squeeze */
WINBASEAPI BOOL WINAPI CheckTokenMembership(HANDLE, PSID, PBOOL);

/* prototypes */
NOEXPORT BOOL CALLBACK enum_windows(HWND, LPARAM);
NOEXPORT void gui_cmdline();
NOEXPORT int initialize_winsock(void);
NOEXPORT int gui_loop();

NOEXPORT void CALLBACK timer_proc(HWND, UINT, UINT_PTR, DWORD);
NOEXPORT LRESULT CALLBACK window_proc(HWND, UINT, WPARAM, LPARAM);
NOEXPORT LRESULT CALLBACK about_proc(HWND, UINT, WPARAM, LPARAM);
NOEXPORT LRESULT CALLBACK pass_proc(HWND, UINT, WPARAM, LPARAM);

NOEXPORT void save_log(void);
NOEXPORT void win_log(LPCTSTR);
NOEXPORT int save_text_file(LPTSTR, char *);
NOEXPORT void update_logs(void);
NOEXPORT LPTSTR log_txt(void);

NOEXPORT void daemon_thread(void *);

NOEXPORT void valid_config(void);
NOEXPORT void invalid_config(void);
NOEXPORT void update_peer_menu(void);
NOEXPORT void tray_update(const int);
NOEXPORT void tray_delete(void);
NOEXPORT void error_box(LPCTSTR);
NOEXPORT void edit_config(HWND);
NOEXPORT BOOL is_admin(void);

/* NT Service related function */
#ifndef _WIN32_WCE
NOEXPORT int service_initialize(void);
NOEXPORT int service_install(void);
NOEXPORT int service_uninstall(void);
NOEXPORT int service_start(void);
NOEXPORT int service_stop(void);
NOEXPORT int service_user(DWORD);
NOEXPORT void WINAPI service_main(DWORD, LPTSTR *);
NOEXPORT void WINAPI control_handler(DWORD);
#endif /* !defined(_WIN32_WCE) */

/* other functions */
NOEXPORT LPTSTR get_params();

/* global variables */
static struct LIST {
  struct LIST *next;
  size_t len;
  TCHAR txt[1]; /* single character for trailing '\0' */
} *head=NULL, *tail=NULL;

static unsigned number_of_sections=0;

static HINSTANCE ghInst;
static HWND edit_handle=NULL;
static HMENU tray_menu_handle=NULL;
#ifndef _WIN32_WCE
static HMENU main_menu_handle=NULL;
#endif
static HWND hwnd=NULL; /* main window handle */
#ifdef _WIN32_WCE
static HWND command_bar_handle; /* command bar handle */
#endif
    /* win32_name is needed for any error_box(), message_box(),
     * and the initial main window title */
static TCHAR *win32_name=TEXT("stunnel ") TEXT(STUNNEL_VERSION)
    TEXT(" on ") TEXT(STUNNEL_PLATFORM) TEXT(" (not configured)");

#ifndef _WIN32_WCE
static SERVICE_STATUS serviceStatus;
static SERVICE_STATUS_HANDLE serviceStatusHandle=0;
#define SERVICE_CONTROL_USER 128
#endif

static BOOL visible=FALSE;
static HANDLE main_initialized=NULL; /* global initialization performed */
static HANDLE config_ready=NULL; /* reload without a valid configuration */
static LONG new_logs=0;

static UI_DATA *ui_data=NULL;

static struct {
    char *config_file;
    unsigned service:1, install:1, uninstall:1, start:1, stop:1,
        quiet:1, exit:1, reload:1, reopen:1;
} cmdline;

/**************************************** initialization */

int WINAPI WinMain(HINSTANCE this_instance, HINSTANCE prev_instance,
#ifdef _WIN32_WCE
        LPWSTR lpCmdLine,
#else
        LPSTR lpCmdLine,
#endif
        int nCmdShow) {
    TCHAR stunnel_exe_path[MAX_PATH];
    LPTSTR c;
#ifndef _WIN32_WCE
    LPTSTR errmsg;
#endif

    (void)prev_instance; /* skip warning about unused parameter */
    (void)lpCmdLine; /* skip warning about unused parameter */
    (void)nCmdShow; /* skip warning about unused parameter */

    tls_init(); /* initialize thread-local storage */
    ghInst=this_instance;
    gui_cmdline(); /* setup global cmdline structure */
    GetModuleFileName(0, stunnel_exe_path, MAX_PATH);

#ifndef _WIN32_WCE
    /* find previous instances of the same executable */
    if(!cmdline.service && !cmdline.install && !cmdline.uninstall &&
            !cmdline.reload && !cmdline.reopen &&
            !cmdline.start && !cmdline.stop) {
        EnumWindows(enum_windows, (LPARAM)stunnel_exe_path);
        if(cmdline.exit)
            return 0; /* in case EnumWindows didn't find a previous instance */
    }
#endif

    /* set current working directory and engine path */
    c=_tcsrchr(stunnel_exe_path, TEXT('\\')); /* last backslash */
    if(c) /* found */
        c[1]=TEXT('\0'); /* truncate program name */
#ifndef _WIN32_WCE
    if(!SetCurrentDirectory(stunnel_exe_path)) {
        errmsg=str_tprintf(TEXT("Cannot set directory to %s"),
            stunnel_exe_path);
        message_box(errmsg, MB_ICONERROR);
        str_free(errmsg);
        return 1;
    }
#endif
    _tputenv(str_tprintf(TEXT("OPENSSL_ENGINES=%s"), stunnel_exe_path));

    if(initialize_winsock())
        return 1;

#ifndef _WIN32_WCE
    if(cmdline.service) /* "-service" must be processed before "-install" */
        return service_initialize();
    if(cmdline.install)
        return service_install();
    if(cmdline.uninstall)
        return service_uninstall();
    if(cmdline.start)
        return service_start();
    if(cmdline.stop)
        return service_stop();
    if(cmdline.reload)
        return service_user(SIGNAL_RELOAD_CONFIG);
    if(cmdline.reopen)
        return service_user(SIGNAL_REOPEN_LOG);
#endif
    return gui_loop();
}

#ifndef _WIN32_WCE

NOEXPORT BOOL CALLBACK enum_windows(HWND other_window_handle, LPARAM lParam) {
    DWORD pid;
    HINSTANCE hInstance;
    HANDLE process_handle;
    TCHAR window_exe_path[MAX_PATH];
    LPTSTR stunnel_exe_path=(LPTSTR)lParam;

    if(!other_window_handle)
        return TRUE;
    hInstance=(HINSTANCE)GetWindowLong(other_window_handle, GWL_HINSTANCE);
    GetWindowThreadProcessId(other_window_handle, &pid);
    process_handle=OpenProcess(SYNCHRONIZE|         /* WaitForSingleObject() */
        PROCESS_TERMINATE|                          /* TerminateProcess()    */
        PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,  /* GetModuleFileNameEx() */
        FALSE, pid);
    if(!process_handle)
        return TRUE;
    if(!GetModuleFileNameEx(process_handle,
            hInstance, window_exe_path, MAX_PATH)) {
        CloseHandle(process_handle);
        return TRUE;
    }
    if(_tcscmp(stunnel_exe_path, window_exe_path)) {
        CloseHandle(process_handle);
        return TRUE;
    }
    if(cmdline.exit) {
        PostMessage(other_window_handle, WM_COMMAND, IDM_EXIT, 0);
        if(WaitForSingleObject(process_handle, 3000)==WAIT_TIMEOUT) {
            TerminateProcess(process_handle, 0);
            WaitForSingleObject(process_handle, 3000);
        }
    } else {
        ShowWindow(other_window_handle, SW_SHOWNORMAL); /* show window */
        SetForegroundWindow(other_window_handle); /* bring on top */
    }
    CloseHandle(process_handle);
    exit(0);
    return FALSE; /* should never be executed */
}

#endif

NOEXPORT void gui_cmdline() {
    char *line, *c, *opt;

    line=tstr2str(get_params());
    memset(&cmdline, 0, sizeof cmdline);
    c=line;
    while(*c && (*c=='/' || *c=='-')) {
        opt=c;
        while(*c && !isspace(*c)) /* skip non-whitespaces */
            c++;
        while(*c && isspace(*c)) /* replace whitespaces with '\0' */
            *c++='\0';
        if(!strcasecmp(opt+1, "install"))
            cmdline.install=1;
        else if(!strcasecmp(opt+1, "uninstall"))
            cmdline.uninstall=1;
        else if(!strcasecmp(opt+1, "reload"))
            cmdline.reload=1;
        else if(!strcasecmp(opt+1, "reopen"))
            cmdline.reopen=1;
        else if(!strcasecmp(opt+1, "start"))
            cmdline.start=1;
        else if(!strcasecmp(opt+1, "stop"))
            cmdline.stop=1;
        else if(!strcasecmp(opt+1, "service"))
            cmdline.service=1;
        else if(!strcasecmp(opt+1, "quiet"))
            cmdline.quiet=1;
        else if(!strcasecmp(opt+1, "exit"))
            cmdline.exit=1;
        else { /* an option to be processed in options.c */
            c=opt;
            break;
        }
    }
    if(*c=='\"') { /* the option is within double quotes */
        c++;
        opt=c;
        while(*c && *c!='\"') /* find the closing double quote */
            c++;
        *c='\0';
    } else /* the option is simply the rest of the line */
        opt=c;
    cmdline.config_file=*opt ? str_dup(opt) : NULL;
    str_free(line);
}

/* try to load winsock2 resolver functions from a specified dll name */
NOEXPORT int initialize_winsock() {
    static struct WSAData wsa_state;

    if(WSAStartup(MAKEWORD( 2, 2 ), &wsa_state)) {
        message_box(TEXT("Failed to initialize winsock"), MB_ICONERROR);
        return 1; /* error */
    }
    resolver_init();
    return 0; /* IPv4 detected -> OK */
}

/**************************************** GUI thread */

NOEXPORT int gui_loop() {
#ifdef _WIN32_WCE
    WNDCLASS wc;
#else
    WNDCLASSEX wc;
#endif
    MSG msg;
    LPTSTR classname=TEXT("stunnel_main_window_class");

    /* register the class */
#ifndef _WIN32_WCE
    wc.cbSize=sizeof wc;
#endif
    wc.style=CS_VREDRAW|CS_HREDRAW;
    wc.lpfnWndProc=window_proc;
    wc.cbClsExtra=wc.cbWndExtra=0;
    wc.hInstance=ghInst;
    wc.hIcon=LoadIcon(ghInst, MAKEINTRESOURCE(IDI_STUNNEL_MAIN));
    wc.hCursor=LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName=NULL;
    wc.lpszClassName=classname;
#ifdef _WIN32_WCE
    RegisterClass(&wc);
#else
    /* load 16x16 icon */
    wc.hIconSm=LoadImage(ghInst, MAKEINTRESOURCE(IDI_STUNNEL_MAIN), IMAGE_ICON,
        GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
    RegisterClassEx(&wc);
#endif

    /* create main window */
#ifdef _WIN32_WCE
    hwnd=CreateWindow(classname, win32_name, 0,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, ghInst, NULL);
#else
    main_menu_handle=LoadMenu(ghInst, MAKEINTRESOURCE(IDM_MAINMENU));
    if(main_menu_handle && cmdline.service) {
        /* block unsafe operations in the service mode */
        EnableMenuItem(main_menu_handle, IDM_EDIT_CONFIG, MF_GRAYED);
        EnableMenuItem(main_menu_handle, IDM_SAVE_LOG, MF_GRAYED);
    }
    hwnd=CreateWindow(classname, win32_name, WS_TILEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, main_menu_handle, ghInst, NULL);
#endif

    /* auto-reset, non-signaled events */
    main_initialized=CreateEvent(NULL, FALSE, FALSE, NULL);
    config_ready=CreateEvent(NULL, FALSE, FALSE, NULL);
    /* hwnd needs to be initialized before _beginthread() */
    _beginthread(daemon_thread, DEFAULT_STACK_SIZE, NULL);
    WaitForSingleObject(main_initialized, INFINITE);
    /* logging subsystem is now available */

    /* setup periodic event to trigger update_logs() */
    SetTimer(NULL, 0, 1000, timer_proc); /* run callback once per second */

    s_log(LOG_DEBUG, "GUI message loop initialized");
    for(;;)
        switch(GetMessage(&msg, NULL, 0, 0)) {
        case -1:
            ioerror("GetMessage");
            return 0;
        case 0:
            s_log(LOG_DEBUG, "GUI message loop terminated");
            return (int)msg.wParam;
        default:
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
}

NOEXPORT void CALLBACK timer_proc(HWND hwnd, UINT msg, UINT_PTR id, DWORD t) {
    (void)hwnd; /* skip warning about unused parameter */
    (void)msg; /* skip warning about unused parameter */
    (void)id; /* skip warning about unused parameter */
    (void)t; /* skip warning about unused parameter */
    if(visible)
        update_logs();
    tray_update(num_clients); /* needed when explorer.exe (re)starts */
}

NOEXPORT LRESULT CALLBACK window_proc(HWND main_window_handle,
        UINT message, WPARAM wParam, LPARAM lParam) {
    POINT pt;
    RECT rect;
    PAINTSTRUCT ps;
    SERVICE_OPTIONS *section;
    unsigned section_number;
    LPTSTR txt;

#if 0
    switch(message) {
    case WM_CTLCOLORSTATIC:
    case WM_TIMER:
    case WM_LOG:
        break;
    default:
        s_log(LOG_DEBUG, "Window message: 0x%x(0x%hx,0x%lx)",
            message, wParam, lParam);
    }
#endif
    switch(message) {
    case WM_CREATE:
#ifdef _WIN32_WCE
        /* create command bar */
        command_bar_handle=CommandBar_Create(ghInst, main_window_handle, 1);
        if(!command_bar_handle)
            error_box(TEXT("CommandBar_Create"));
        if(!CommandBar_InsertMenubar(command_bar_handle, ghInst, IDM_MAINMENU, 0))
            error_box(TEXT("CommandBar_InsertMenubar"));
        if(!CommandBar_AddAdornments(command_bar_handle, 0, 0))
            error_box(TEXT("CommandBar_AddAdornments"));
#endif

        /* create child edit window */
        edit_handle=CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL,
            WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_READONLY,
            0, 0, 0, 0, main_window_handle, (HMENU)IDE_EDIT, ghInst, NULL);
#ifndef _WIN32_WCE
        SendMessage(edit_handle, WM_SETFONT,
            (WPARAM)CreateFont(-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
                DEFAULT_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,
                PROOF_QUALITY, DEFAULT_PITCH, TEXT("Courier")),
            MAKELPARAM(FALSE, 0)); /* no need to redraw right now */
#endif
        /* NOTE: there's no return statement here -> proceeding with resize */

    case WM_SIZE:
        GetClientRect(main_window_handle, &rect);
#ifdef _WIN32_WCE
        MoveWindow(edit_handle, 0, CommandBar_Height(command_bar_handle),
            rect.right, rect.bottom-CommandBar_Height(command_bar_handle),
            TRUE);
        SendMessage(command_bar_handle, TB_AUTOSIZE, 0L, 0L);
        CommandBar_AlignAdornments(command_bar_handle);
#else
        MoveWindow(edit_handle, 0, 0, rect.right, rect.bottom, TRUE);
#endif
        UpdateWindow(edit_handle);
        /* CommandBar_Show(command_bar_handle, TRUE); */
        return 0;

    case WM_SETFOCUS:
        SetFocus(edit_handle);
        return 0;

    case WM_PAINT:
        BeginPaint(hwnd, &ps);
        EndPaint(hwnd, &ps);
        break;

    case WM_CLOSE:
        ShowWindow(main_window_handle, SW_HIDE);
        return 0;

#ifdef WM_SHOWWINDOW
    case WM_SHOWWINDOW:
        visible=(BOOL)wParam;
#else /* this works for Pierre Delaage, but not for me... */
    case WM_WINDOWPOSCHANGED:
        visible=IsWindowVisible(main_window_handle);
#endif
        if(tray_menu_handle)
            CheckMenuItem(tray_menu_handle, IDM_SHOW_LOG,
                visible ? MF_CHECKED : MF_UNCHECKED);
        if(visible)
            update_logs();
#ifdef WM_SHOWWINDOW
        return 0;
#else
        break; /* proceed to DefWindowProc() */
#endif

    case WM_DESTROY:
#ifdef _WIN32_WCE
        CommandBar_Destroy(command_bar_handle);
#else
        if(main_menu_handle) {
            if(!DestroyMenu(main_menu_handle))
                ioerror("DestroyMenu");
            main_menu_handle=NULL;
        }
#endif
        tray_delete(); /* remove the taskbark icon if exists */
        PostQuitMessage(0);
        return 0;

    case WM_COMMAND:
        if(wParam>=IDM_PEER_MENU && wParam<IDM_PEER_MENU+number_of_sections) {
            for(section=service_options.next, section_number=0;
                    section && wParam!=IDM_PEER_MENU+section_number;
                    section=section->next, ++section_number)
                ;
            if(!section)
                return 0;
            if(save_text_file(section->file, section->chain))
                return 0;
#ifndef _WIN32_WCE
            if(main_menu_handle)
                CheckMenuItem(main_menu_handle, wParam, MF_CHECKED);
#endif
            if(tray_menu_handle)
                CheckMenuItem(tray_menu_handle, wParam, MF_CHECKED);
            message_box(section->help, MB_ICONINFORMATION);
            return 0;
        }
        switch(wParam) {
        case IDM_ABOUT:
            DialogBox(ghInst, TEXT("AboutBox"), main_window_handle,
                (DLGPROC)about_proc);
            break;
        case IDM_SHOW_LOG:
            if(visible) {
                ShowWindow(main_window_handle, SW_HIDE); /* hide window */
            } else {
                ShowWindow(main_window_handle, SW_SHOWNORMAL); /* show window */
                SetForegroundWindow(main_window_handle); /* bring on top */
            }
            break;
        case IDM_CLOSE:
            ShowWindow(main_window_handle, SW_HIDE); /* hide window */
            break;
        case IDM_EXIT:
            if(num_clients>=0) /* signal_pipe is active */
                signal_post(SIGNAL_TERMINATE);
            DestroyWindow(main_window_handle);
            break;
        case IDM_SAVE_LOG:
            if(!cmdline.service) /* security */
                save_log();
            break;
        case IDM_EDIT_CONFIG:
#ifndef _WIN32_WCE
            if(!cmdline.service) /* security */
                edit_config(main_window_handle);
#endif
            break;
        case IDM_RELOAD_CONFIG:
            if(num_clients>=0) /* signal_pipe is active */
                signal_post(SIGNAL_RELOAD_CONFIG);
            else
                SetEvent(config_ready); /* unlock daemon_thread() */
            break;
        case IDM_REOPEN_LOG:
            signal_post(SIGNAL_REOPEN_LOG);
            break;
        case IDM_MANPAGE:
#ifndef _WIN32_WCE
            if(!cmdline.service) /* security */
                ShellExecute(main_window_handle, TEXT("open"),
                    TEXT("stunnel.html"), NULL, NULL, SW_SHOWNORMAL);
#endif
            break;
        case IDM_HOMEPAGE:
#ifndef _WIN32_WCE
            if(!cmdline.service) /* security */
                ShellExecute(main_window_handle, TEXT("open"),
                    TEXT("http://www.stunnel.org/"), NULL, NULL, SW_SHOWNORMAL);
#endif
            break;
        }
        return 0;

    case WM_SYSTRAY: /* a taskbar event */
        switch(lParam) {
#ifdef _WIN32_WCE
        case WM_LBUTTONDOWN: /* no right mouse button on Windows CE */
            GetWindowRect(GetDesktopWindow(), &rect); /* no cursor position */
            pt.x=rect.right;
            pt.y=rect.bottom-25;
#else
        case WM_RBUTTONDOWN:
            GetCursorPos(&pt);
#endif
            SetForegroundWindow(main_window_handle);
            if(tray_menu_handle)
                TrackPopupMenuEx(GetSubMenu(tray_menu_handle, 0),
                    TPM_BOTTOMALIGN, pt.x, pt.y, main_window_handle, NULL);
            PostMessage(main_window_handle, WM_NULL, 0, 0);
            break;
#ifndef _WIN32_WCE
        case WM_LBUTTONDBLCLK: /* switch log window visibility */
            if(visible) {
                ShowWindow(main_window_handle, SW_HIDE); /* hide window */
            } else {
                ShowWindow(main_window_handle, SW_SHOWNORMAL); /* show window */
                SetForegroundWindow(main_window_handle); /* bring on top */
            }
            break;
#endif
        }
        return 0;

    case WM_VALID_CONFIG:
        valid_config();
        return 0;

    case WM_INVALID_CONFIG:
        invalid_config();
        return 0;

    case WM_LOG:
        txt=(LPTSTR)wParam;
        win_log(txt);
        str_free(txt);
        return 0;

    case WM_NEW_CHAIN:
#ifndef _WIN32_WCE
        if(main_menu_handle)
            EnableMenuItem(main_menu_handle, IDM_PEER_MENU+wParam, MF_ENABLED);
#endif
        if(tray_menu_handle)
            EnableMenuItem(tray_menu_handle, IDM_PEER_MENU+wParam, MF_ENABLED);
        return 0;

    case WM_CLIENTS:
        tray_update((int)wParam);
        return 0;
    }

    return DefWindowProc(main_window_handle, message, wParam, lParam);
}

NOEXPORT LRESULT CALLBACK about_proc(HWND dialog_handle, UINT message,
        WPARAM wParam, LPARAM lParam) {
    (void)lParam; /* skip warning about unused parameter */

    switch(message) {
        case WM_INITDIALOG:
            return TRUE;
        case WM_COMMAND:
            switch(wParam) {
                case IDOK:
                case IDCANCEL:
                    EndDialog(dialog_handle, TRUE);
                    return TRUE;
            }
    }
    return FALSE;
}

NOEXPORT LRESULT CALLBACK pass_proc(HWND dialog_handle, UINT message,
        WPARAM wParam, LPARAM lParam) {
    LPTSTR titlebar;
    union {
        TCHAR txt[PEM_BUFSIZE];
        WORD len;
    } pass_dialog;
    WORD pass_len;
    char* pass_txt;
    LPTSTR key_file_name;

    switch(message) {
    case WM_INITDIALOG:
        /* set the default push button to "Cancel" */
        SendMessage(dialog_handle, DM_SETDEFID, (WPARAM)IDCANCEL, (LPARAM)0);

        key_file_name=str2tstr(ui_data->section->key);
        titlebar=str_tprintf(TEXT("Private key: %s"), key_file_name);
        str_free(key_file_name);
        SetWindowText(dialog_handle, titlebar);
        str_free(titlebar);
        return TRUE;

    case WM_COMMAND:
        /* set the default push button to "OK" when the user enters text */
        if(HIWORD(wParam)==EN_CHANGE && LOWORD(wParam)==IDE_PASSEDIT)
            SendMessage(dialog_handle, DM_SETDEFID, (WPARAM)IDOK, (LPARAM)0);
        switch(wParam) {
        case IDOK:
            /* get number of characters */
            pass_len=(WORD)SendDlgItemMessage(dialog_handle,
                IDE_PASSEDIT, EM_LINELENGTH, (WPARAM)0, (LPARAM)0);
            if(!pass_len || pass_len>=PEM_BUFSIZE) {
                EndDialog(dialog_handle, FALSE);
                return FALSE;
            }

            /* put the number of characters into first word of buffer */
            pass_dialog.len=pass_len;

            /* get the characters */
            SendDlgItemMessage(dialog_handle, IDE_PASSEDIT, EM_GETLINE,
                (WPARAM)0 /* line 0 */, (LPARAM)pass_dialog.txt);
            pass_dialog.txt[pass_len]='\0'; /* null-terminate the string */

            /* convert input password to UTF-8 string (as ui_data->pass) */
            pass_txt=tstr2str(pass_dialog.txt);
            strcpy(ui_data->pass, pass_txt);
            str_free(pass_txt);

            EndDialog(dialog_handle, TRUE);
            return TRUE;

        case IDCANCEL:
            EndDialog(dialog_handle, FALSE);
            return TRUE;
        }
        return 0;
    }
    return FALSE;

    UNREFERENCED_PARAMETER(lParam);
}

int passwd_cb(char *buf, int size, int rwflag, void *userdata) {
    (void)rwflag; /* skip warning about unused parameter */

    ui_data=userdata;
    if(size<0) /* just in case */
        return 0;
    if(!DialogBox(ghInst, TEXT("PassBox"), hwnd, (DLGPROC)pass_proc))
        return 0; /* error */
    strncpy(buf, ui_data->pass, (size_t)size);
    buf[size-1]='\0';
    return (int)strlen(buf);
}

#ifndef OPENSSL_NO_ENGINE
int pin_cb(UI *ui, UI_STRING *uis) {
    ui_data=UI_get0_user_data(ui); /* was: ui_data=UI_get_app_data(ui); */
    if(!ui_data) {
        s_log(LOG_ERR, "INTERNAL ERROR: user data data pointer");
        return 0;
    }
    if(!DialogBox(ghInst, TEXT("PassBox"), hwnd, (DLGPROC)pass_proc))
        return 0; /* error */
    UI_set_result(ui, uis, ui_data->pass);
    return 1;
}
#endif

/**************************************** log handling */

NOEXPORT void save_log() {
    TCHAR file_name[MAX_PATH];
    OPENFILENAME ofn;
    LPTSTR txt;
    LPSTR str;

    ZeroMemory(&ofn, sizeof ofn);
    file_name[0]='\0';

    ofn.lStructSize=sizeof ofn;
    ofn.hwndOwner=hwnd;
    ofn.lpstrFilter=TEXT("Log Files (*.log)\0*.log\0All Files (*.*)\0*.*\0\0");
    ofn.lpstrFile=file_name;
    ofn.nMaxFile=MAX_PATH;
    ofn.lpstrDefExt=TEXT("LOG");
    ofn.lpstrInitialDir=TEXT(".");

    ofn.lpstrTitle=TEXT("Save Log");
    ofn.Flags=OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|
        OFN_OVERWRITEPROMPT;
    if(!GetSaveFileName(&ofn))
        return;

    txt=log_txt(); /* need to convert the result to UTF-8 */
    str=tstr2str(txt);
    str_free(txt);
    save_text_file(file_name, str);
    str_free(str);
}

NOEXPORT int save_text_file(LPTSTR file_name, char *str) {
    HANDLE file_handle;
    DWORD ignore;

    file_handle=CreateFile(file_name, GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if(file_handle==INVALID_HANDLE_VALUE) {
        error_box(TEXT("CreateFile"));
        return 1;
    }
    if(!WriteFile(file_handle, str, strlen(str), &ignore, NULL)) {
        CloseHandle(file_handle);
        error_box(TEXT("WriteFile"));
        return 1;
    }
    CloseHandle(file_handle);
    return 0;
}

NOEXPORT void win_log(LPCTSTR txt) {
    struct LIST *curr;
    size_t txt_len;
    static size_t log_len=0;

    txt_len=_tcslen(txt);
    curr=str_alloc(sizeof(struct LIST)+txt_len*sizeof(TCHAR));
    curr->len=txt_len;
    _tcscpy(curr->txt, txt);
    curr->next=NULL;
    if(tail)
        tail->next=curr;
    tail=curr;
    if(!head)
        head=tail;
    log_len++;
    while(log_len>LOG_LINES) {
        curr=head;
        head=head->next;
        str_free(curr);
        log_len--;
    }
    new_logs=1;
}

NOEXPORT void update_logs(void) {
    LPTSTR txt;

    if(!InterlockedExchange(&new_logs, 0))
        return;
    txt=log_txt();
    SetWindowText(edit_handle, txt);
    str_free(txt);
    SendMessage(edit_handle, WM_VSCROLL, (WPARAM)SB_BOTTOM, (LPARAM)0);
}

NOEXPORT LPTSTR log_txt(void) {
    LPTSTR buff;
    unsigned ptr=0, len=0;
    struct LIST *curr;

    for(curr=head; curr; curr=curr->next)
        len+=curr->len+2; /* +2 for trailing '\r\n' */
    buff=str_alloc((len+1)*sizeof(TCHAR)); /* +1 for trailing '\0' */
    for(curr=head; curr; curr=curr->next) {
        memcpy(buff+ptr, curr->txt, curr->len*sizeof(TCHAR));
        ptr+=curr->len;
        if(curr->next) {
            buff[ptr++]=TEXT('\r');
            buff[ptr++]=TEXT('\n');
        }
    }
    buff[ptr]=TEXT('\0');
    return buff;
}

/**************************************** worker thread */

NOEXPORT void daemon_thread(void *arg) {
    (void)arg; /* skip warning about unused parameter */

    tls_alloc(NULL, NULL, "main"); /* new thread-local storage */
    main_init();
    SetEvent(main_initialized); /* unlock the GUI thread */
    /* get a valid configuration */
    while(main_configure(cmdline.config_file, NULL)) {
        cmdline.config_file=NULL; /* don't retry commandline switches */
        unbind_ports(); /* in case initialization failed after bind_ports() */
        log_flush(LOG_MODE_ERROR); /* otherwise logs are buffered */
        PostMessage(hwnd, WM_INVALID_CONFIG, 0, 0); /* display error */
        WaitForSingleObject(config_ready, INFINITE);
        log_close(); /* prevent main_configure() from logging in error mode */
    }
    PostMessage(hwnd, WM_VALID_CONFIG, 0, 0);

    /* start the main loop */
    daemon_loop();
    main_cleanup();
    _endthread(); /* SIGNAL_TERMINATE received */
}

/**************************************** helper functions */

NOEXPORT void invalid_config() {
    /* update the main window title */
    win32_name=TEXT("stunnel ") TEXT(STUNNEL_VERSION) TEXT(" on ")
        TEXT(STUNNEL_PLATFORM) TEXT(" (invalid configuration file)");
    SetWindowText(hwnd, win32_name);

    /* log window is hidden by default */
    ShowWindow(hwnd, SW_SHOWNORMAL); /* show window */
    SetForegroundWindow(hwnd); /* bring on top */

    tray_update(-1); /* error icon */
    update_peer_menu(); /* purge the list of sections */

    win_log(TEXT(""));
    s_log(LOG_ERR, "Server is down");
    message_box(TEXT("Stunnel server is down due to an error.\n")
        TEXT("You need to exit and correct the problem.\n")
        TEXT("Click OK to see the error log window."),
        MB_ICONERROR);
}

NOEXPORT void valid_config() {
    /* update the main window title */
    win32_name=TEXT("stunnel ") TEXT(STUNNEL_VERSION) TEXT(" on ")
        TEXT(STUNNEL_PLATFORM);
    SetWindowText(hwnd, win32_name);

    tray_update(num_clients); /* idle or busy icon (on reload) */
    update_peer_menu(); /* one menu item per section */

    /* enable IDM_REOPEN_LOG menu if a log file is used, disable otherwise */
#ifndef _WIN32_WCE
    EnableMenuItem(main_menu_handle, IDM_REOPEN_LOG,
        (UINT)(global_options.output_file ? MF_ENABLED : MF_GRAYED));
#endif
    if(tray_menu_handle)
        EnableMenuItem(tray_menu_handle, IDM_REOPEN_LOG,
            (UINT)(global_options.output_file ? MF_ENABLED : MF_GRAYED));
}

NOEXPORT void update_peer_menu(void) {
    SERVICE_OPTIONS *section;
#ifndef _WIN32_WCE
    HMENU main_peer_list=NULL;
#endif
    HMENU tray_peer_list=NULL;
    unsigned section_number;
    LPTSTR servname;

    /* purge menu peer lists */
#ifndef _WIN32_WCE
    if(main_menu_handle)
        main_peer_list=GetSubMenu(main_menu_handle, 2); /* 3rd submenu */
    if(main_peer_list)
        while(GetMenuItemCount(main_peer_list)) /* purge old menu */
            DeleteMenu(main_peer_list, 0, MF_BYPOSITION);
#endif
    if(tray_menu_handle)
        tray_peer_list=GetSubMenu(GetSubMenu(tray_menu_handle, 0), 2);
    if(tray_peer_list)
        while(GetMenuItemCount(tray_peer_list)) /* purge old menu */
            DeleteMenu(tray_peer_list, 0, MF_BYPOSITION);

    /* initialize data structures */
    number_of_sections=0;
    for(section=service_options.next; section; section=section->next)
        section->section_number=number_of_sections++;

    section_number=0;
    for(section=service_options.next; section; section=section->next) {
        servname=str2tstr(section->servname);

        /* setup LPTSTR section->file */
        section->file=str_tprintf(TEXT("peer-%s.pem"), servname);

        /* setup section->help */
        section->help=str_tprintf(
            TEXT("Peer certificate chain has been saved.\n")
            TEXT("Add the following lines to section [%s]:\n")
            TEXT("\tCAfile = peer-%s.pem\n")
            TEXT("\tverify = 3\n")
            TEXT("to enable cryptographic authentication.\n")
            TEXT("Then reload stunnel configuration file."),
            servname, servname);

        str_free(servname);

        /* setup section->chain */
        section->chain=NULL;

        /* insert new menu item */
#ifndef _WIN32_WCE
        if(main_peer_list)
            if(!InsertMenu(main_peer_list, section_number,
                    MF_BYPOSITION|MF_STRING|MF_GRAYED,
                    IDM_PEER_MENU+section_number, section->file))
                ioerror("InsertMenu");
#endif
        if(tray_peer_list)
            if(!InsertMenu(tray_peer_list, section_number,
                    MF_BYPOSITION|MF_STRING|MF_GRAYED,
                    IDM_PEER_MENU+section_number, section->file))
                ioerror("InsertMenu");

        ++section_number;
    }
    if(hwnd)
        DrawMenuBar(hwnd);
}

ICON_IMAGE load_icon_default(ICON_TYPE type) {
    WORD idi;
    ICON_IMAGE img;

    switch(type) {
    case ICON_ACTIVE:
        idi=IDI_STUNNEL_ACTIVE;
        break;
    case ICON_ERROR:
        idi=IDI_STUNNEL_ERROR;
        break;
    case ICON_IDLE:
        idi=IDI_STUNNEL_IDLE;
        break;
    default:
        return NULL;
    }
    img=LoadImage(ghInst, MAKEINTRESOURCE(idi), IMAGE_ICON,
        GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
    return DuplicateIcon(NULL, img);
}

ICON_IMAGE load_icon_file(const char *name) {
    LPTSTR tname;
    ICON_IMAGE icon;

    tname=str2tstr((LPSTR)name);
#ifndef _WIN32_WCE
    icon=LoadImage(NULL, tname, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
        GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE);
#else
    /* TODO: Implement a WCE version of LoadImage() */
    /* icon=wceLoadIconFromFile(tname); */
    s_log(LOG_ERR, "Loading image from file not implemented on WCE");
    icon=NULL;
#endif
    str_free(tname);
    return icon;
}

NOEXPORT void tray_update(const int num) {
    NOTIFYICONDATA nid;
    static ICON_TYPE previous_icon=ICON_NONE;
    ICON_TYPE current_icon;
    LPTSTR tip;

    if(!global_options.option.taskbar) { /* currently disabled */
        tray_delete(); /* remove the taskbark icon if exists */
        return;
    }
    if(!tray_menu_handle) /* initialize taskbar */
        tray_menu_handle=LoadMenu(ghInst, MAKEINTRESOURCE(IDM_TRAYMENU));
    if(!tray_menu_handle) {
        ioerror("LoadMenu");
        return;
    }
    if(cmdline.service)
        EnableMenuItem(tray_menu_handle, IDM_EDIT_CONFIG, MF_GRAYED);

    ZeroMemory(&nid, sizeof nid);
    nid.cbSize=sizeof nid;
    nid.uID=1; /* application-defined icon ID */
    nid.uFlags=NIF_MESSAGE|NIF_TIP;
    nid.uCallbackMessage=WM_SYSTRAY; /* notification message */
    nid.hWnd=hwnd; /* window to receive notifications */
    if(num<0) {
        tip=str_tprintf(TEXT("Server is down"));
        current_icon=ICON_ERROR;
    } else if(num>0) {
        tip=str_tprintf(TEXT("%d active session(s)"), num);
        current_icon=ICON_ACTIVE;
    } else {
        tip=str_tprintf(TEXT("Server is idle"));
        current_icon=ICON_IDLE;
    }
    _tcsncpy(nid.szTip, tip, 63);
    nid.szTip[63]=TEXT('\0');
    str_free(tip);
    nid.hIcon=global_options.icon[current_icon];
    if(current_icon!=previous_icon) {
        nid.uFlags|=NIF_ICON;
        previous_icon=current_icon;
    }
    if(Shell_NotifyIcon(NIM_MODIFY, &nid)) /* modify tooltip */
        return; /* OK: taskbar icon exists */
    /* tooltip update failed - try to create the icon */
    nid.uFlags|=NIF_ICON;
    Shell_NotifyIcon(NIM_ADD, &nid);
}

NOEXPORT void tray_delete(void) {
    NOTIFYICONDATA nid;

    if(tray_menu_handle) {
        ZeroMemory(&nid, sizeof nid);
        nid.cbSize=sizeof nid;
        nid.uID=1; /* application-defined icon ID */
        nid.hWnd=hwnd; /* window to receive notifications */
        nid.uFlags=NIF_TIP; /* not really sure what to put here, but it works */
        Shell_NotifyIcon(NIM_DELETE, &nid); /* this removes the icon */
        if(!DestroyMenu(tray_menu_handle)) /* release menu resources */
            ioerror("DestroyMenu");
        tray_menu_handle=NULL;
    }
}

NOEXPORT void error_box(LPCTSTR text) {
    LPTSTR errmsg, fullmsg;
    DWORD dw;

    dw=GetLastError();
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&errmsg, 0, NULL);
    fullmsg=str_tprintf(TEXT("%s: error %ld: %s"), text, dw, errmsg);
    LocalFree(errmsg);
    message_box(fullmsg, MB_ICONERROR);
    str_free(fullmsg);
}

void message_box(LPCTSTR text, const UINT type) {
    if(cmdline.quiet)
        return;
    MessageBox(hwnd, text, win32_name, type);
}

void ui_new_chain(const unsigned section_number) {
    PostMessage(hwnd, WM_NEW_CHAIN, section_number, 0);
}

void ui_new_log(const char *line) {
    LPTSTR txt;
    txt=str2tstr(line);
    str_detach(txt); /* this allocation will be freed in the GUI thread */
    PostMessage(hwnd, WM_LOG, (WPARAM)txt, 0);
}

void ui_config_reloaded(void) {
    PostMessage(hwnd, WM_VALID_CONFIG, 0, 0);
}

void ui_clients(const long num) {
    PostMessage(hwnd, WM_CLIENTS, (WPARAM)num, 0);
}

    /* TODO: port it to WCE */
NOEXPORT void edit_config(HWND main_window_handle) {
    TCHAR cwd[MAX_PATH];
    LPTSTR conf_file, conf_path;

    conf_file=str2tstr(configuration_file);
    if(*conf_file==TEXT('\"')) {
        conf_path=conf_file;
    } else if(_tcschr(conf_file, TEXT('\\'))) {
        conf_path=str_tprintf(TEXT("\"%s\""), conf_file);
        str_free(conf_file);
    } else {
        GetCurrentDirectory(MAX_PATH, cwd);
        conf_path=str_tprintf(TEXT("\"%s\\%s\""), cwd, conf_file);
        str_free(conf_file);
    }

    if(is_admin()) {
        ShellExecute(main_window_handle, TEXT("open"),
            TEXT("notepad.exe"), conf_path,
            NULL, SW_SHOWNORMAL);
    } else { /* UAC workaround */
        ShellExecute(main_window_handle, TEXT("runas"),
            TEXT("notepad.exe"), conf_path,
            NULL, SW_SHOWNORMAL);
    }
    str_free(conf_path);
}

NOEXPORT BOOL is_admin(void) {
#ifndef _WIN32_WCE
    SID_IDENTIFIER_AUTHORITY NtAuthority={SECURITY_NT_AUTHORITY};
    PSID admin_group;
    BOOL retval;

    retval=AllocateAndInitializeSid(&NtAuthority, 2,
        SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0, &admin_group);
    if(retval) {
        if(!CheckTokenMembership(NULL, admin_group, &retval))
            retval=FALSE;
        FreeSid(admin_group);
    }
    return retval;
#else
    return TRUE; /* always an admin on WCE */
#endif
}

/**************************************** windows service */

#ifndef _WIN32_WCE

NOEXPORT int service_initialize(void) {
    SERVICE_TABLE_ENTRY serviceTable[]={{0, 0}, {0, 0}};

    serviceTable[0].lpServiceName=SERVICE_NAME;
    serviceTable[0].lpServiceProc=service_main;
    /* disable taskbar for security */
    /* global_options.option.taskbar=0; */
    if(!StartServiceCtrlDispatcher(serviceTable)) {
        error_box(TEXT("StartServiceCtrlDispatcher"));
        return 1;
    }
    return 0; /* NT service started */
}

#define DESCR_LEN 256

NOEXPORT int service_install() {
    SC_HANDLE scm, service;
    TCHAR stunnel_exe_path[MAX_PATH];
    LPTSTR service_path;
    TCHAR descr_str[DESCR_LEN];
    SERVICE_DESCRIPTION descr;

    scm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
    if(!scm) {
        error_box(TEXT("OpenSCManager"));
        return 1;
    }
    GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
    service_path=str_tprintf(TEXT("\"%s\" -service %s"),
        stunnel_exe_path, get_params());
    service=CreateService(scm, SERVICE_NAME, SERVICE_DISPLAY_NAME,
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
        SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, service_path,
        NULL, NULL, TEXT("TCPIP\0"), NULL, NULL);
    if(!service) {
        error_box(TEXT("CreateService"));
        str_free(service_path);
        CloseServiceHandle(scm);
        return 1;
    }
    str_free(service_path);
    if(LoadString(ghInst, IDS_SERVICE_DESC, descr_str, DESCR_LEN)) {
        descr.lpDescription=descr_str;
        ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &descr);
    }
    message_box(TEXT("Service installed"), MB_ICONINFORMATION);
    CloseServiceHandle(service);
    CloseServiceHandle(scm);
    return 0;
}

NOEXPORT int service_uninstall(void) {
    SC_HANDLE scm, service;
    SERVICE_STATUS serviceStatus;

    scm=OpenSCManager(0, 0, SC_MANAGER_CONNECT);
    if(!scm) {
        error_box(TEXT("OpenSCManager"));
        return 1;
    }
    service=OpenService(scm, SERVICE_NAME, SERVICE_QUERY_STATUS|DELETE);
    if(!service) {
        error_box(TEXT("OpenService"));
        CloseServiceHandle(scm);
        return 1;
    }
    if(!QueryServiceStatus(service, &serviceStatus)) {
        error_box(TEXT("QueryServiceStatus"));
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    if(serviceStatus.dwCurrentState!=SERVICE_STOPPED) {
        message_box(TEXT("The service is still running"), MB_ICONERROR);
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    if(!DeleteService(service)) {
        error_box(TEXT("DeleteService"));
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    message_box(TEXT("Service uninstalled"), MB_ICONINFORMATION);
    CloseServiceHandle(service);
    CloseServiceHandle(scm);
    return 0;
}

NOEXPORT int service_start(void) {
    SC_HANDLE scm, service;
    SERVICE_STATUS serviceStatus;

    scm=OpenSCManager(0, 0, SC_MANAGER_CONNECT);
    if(!scm) {
        error_box(TEXT("OpenSCManager"));
        return 1;
    }
    service=OpenService(scm, SERVICE_NAME, SERVICE_QUERY_STATUS|SERVICE_START);
    if(!service) {
        error_box(TEXT("OpenService"));
        CloseServiceHandle(scm);
        return 1;
    }
    if(!StartService(service, 0, NULL)) {
        error_box(TEXT("StartService"));
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    do {
        Sleep(1000);
        if(!QueryServiceStatus(service, &serviceStatus)) {
            error_box(TEXT("QueryServiceStatus"));
            CloseServiceHandle(service);
            CloseServiceHandle(scm);
            return 1;
        }
    } while(serviceStatus.dwCurrentState==SERVICE_START_PENDING);
    if(serviceStatus.dwCurrentState!=SERVICE_RUNNING) {
        message_box(TEXT("Failed to start service"), MB_ICONERROR);
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    message_box(TEXT("Service started"), MB_ICONINFORMATION);
    CloseServiceHandle(service);
    CloseServiceHandle(scm);
    return 0;
}

NOEXPORT int service_stop(void) {
    SC_HANDLE scm, service;
    SERVICE_STATUS serviceStatus;

    scm=OpenSCManager(0, 0, SC_MANAGER_CONNECT);
    if(!scm) {
        error_box(TEXT("OpenSCManager"));
        return 1;
    }
    service=OpenService(scm, SERVICE_NAME, SERVICE_QUERY_STATUS|SERVICE_STOP);
    if(!service) {
        error_box(TEXT("OpenService"));
        CloseServiceHandle(scm);
        return 1;
    }
    if(!QueryServiceStatus(service, &serviceStatus)) {
        error_box(TEXT("QueryServiceStatus"));
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    if(serviceStatus.dwCurrentState==SERVICE_STOPPED) {
        message_box(TEXT("The service is already stopped"), MB_ICONERROR);
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    if(!ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus)) {
        error_box(TEXT("ControlService"));
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    do {
        Sleep(1000);
        if(!QueryServiceStatus(service, &serviceStatus)) {
            error_box(TEXT("QueryServiceStatus"));
            CloseServiceHandle(service);
            CloseServiceHandle(scm);
            return 1;
        }
    } while(serviceStatus.dwCurrentState!=SERVICE_STOPPED);
    message_box(TEXT("Service stopped"), MB_ICONINFORMATION);
    CloseServiceHandle(service);
    CloseServiceHandle(scm);
    return 0;
}

NOEXPORT int service_user(DWORD sig) {
    SC_HANDLE scm, service;
    SERVICE_STATUS serviceStatus;

    scm=OpenSCManager(0, 0, SC_MANAGER_CONNECT);
    if(!scm) {
        error_box(TEXT("OpenSCManager"));
        return 1;
    }
    service=OpenService(scm, SERVICE_NAME,
        SERVICE_QUERY_STATUS|SERVICE_USER_DEFINED_CONTROL);
    if(!service) {
        error_box(TEXT("OpenService"));
        CloseServiceHandle(scm);
        return 1;
    }
    if(!QueryServiceStatus(service, &serviceStatus)) {
        error_box(TEXT("QueryServiceStatus"));
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    if(serviceStatus.dwCurrentState==SERVICE_STOPPED) {
        message_box(TEXT("The service is stopped"), MB_ICONERROR);
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    if(!ControlService(service, SERVICE_CONTROL_USER+sig, &serviceStatus)) {
        error_box(TEXT("ControlService"));
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return 1;
    }
    switch(sig) {
        case SIGNAL_RELOAD_CONFIG:
            message_box(TEXT("Service configuration reloaded"),
                MB_ICONINFORMATION);
            break;
        case SIGNAL_REOPEN_LOG:
            message_box(TEXT("Service log file reopened"),
                MB_ICONINFORMATION);
            break;
        default:
            message_box(TEXT("Undefined operation requested"),
                MB_ICONINFORMATION);
    }
    CloseServiceHandle(service);
    CloseServiceHandle(scm);
    return 0;
}

NOEXPORT void WINAPI service_main(DWORD argc, LPTSTR* argv) {
    (void)argc; /* skip warning about unused parameter */
    (void)argv; /* skip warning about unused parameter */

    tls_alloc(NULL, NULL, "service"); /* new thread-local storage */

    /* initialise service status */
    serviceStatus.dwServiceType=SERVICE_WIN32;
    serviceStatus.dwCurrentState=SERVICE_STOPPED;
    serviceStatus.dwControlsAccepted=0;
    serviceStatus.dwWin32ExitCode=NO_ERROR;
    serviceStatus.dwServiceSpecificExitCode=NO_ERROR;
    serviceStatus.dwCheckPoint=0;
    serviceStatus.dwWaitHint=0;

    serviceStatusHandle=
        RegisterServiceCtrlHandler(SERVICE_NAME, control_handler);

    if(serviceStatusHandle) {
        /* service is starting */
        serviceStatus.dwCurrentState=SERVICE_START_PENDING;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);

        /* running */
        serviceStatus.dwControlsAccepted|=
            (SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN);
        serviceStatus.dwCurrentState=SERVICE_RUNNING;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);

        gui_loop();

        /* service was stopped */
        serviceStatus.dwCurrentState=SERVICE_STOP_PENDING;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);

        /* service is now stopped */
        serviceStatus.dwControlsAccepted&=
            (DWORD)~(SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN);
        serviceStatus.dwCurrentState=SERVICE_STOPPED;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);
    }
}

NOEXPORT void WINAPI control_handler(DWORD controlCode) {
    switch(controlCode) {
    case SERVICE_CONTROL_INTERROGATE:
        break;
    case SERVICE_CONTROL_SHUTDOWN:
    case SERVICE_CONTROL_STOP:
        serviceStatus.dwCurrentState=SERVICE_STOP_PENDING;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);
        PostMessage(hwnd, WM_COMMAND, IDM_EXIT, 0);
        return;
    case SERVICE_CONTROL_PAUSE:
        break;
    case SERVICE_CONTROL_CONTINUE:
        break;
    case SERVICE_CONTROL_USER+SIGNAL_RELOAD_CONFIG:
        signal_post(SIGNAL_RELOAD_CONFIG);
        break;
    case SERVICE_CONTROL_USER+SIGNAL_REOPEN_LOG:
        signal_post(SIGNAL_REOPEN_LOG);
        break;
    default:
        if(controlCode >= 128 && controlCode <= 255)
            break; /* user defined control code */
        else
            break; /* unrecognised control code */
    }
    SetServiceStatus(serviceStatusHandle, &serviceStatus);
}

#endif /* !defined(_WIN32_WCE) */

/**************************************** other functions */

NOEXPORT LPTSTR get_params() {
    LPTSTR c;
    TCHAR s;

    c=GetCommandLine();
    if(*c==TEXT('\"')) {
        s=TEXT('\"');
        ++c;
    } else {
        s=TEXT(' ');
    }
    for(; *c; ++c)
        if(*c==s) {
            ++c;
            break;
        }
    while(*c==TEXT(' '))
        ++c;
    return c;
}

/* end of ui_win_gui.c */
