/*
 * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include "internal/e_os.h"
#include "crypto/cryptlib.h"
#include <openssl/safestack.h>

#if defined(_WIN32) && !defined(OPENSSL_SYS_UEFI)
#include <tchar.h>
#include <signal.h>
#ifdef __WATCOMC__
#if defined(_UNICODE) || defined(__UNICODE__)
#define _vsntprintf _vsnwprintf
#else
#define _vsntprintf _vsnprintf
#endif
#endif
#ifdef _MSC_VER
#define alloca _alloca
#endif

#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0333
#ifdef OPENSSL_SYS_WIN_CORE

int OPENSSL_isservice(void)
{
    /* OneCore API cannot interact with GUI */
    return 1;
}
#else
int OPENSSL_isservice(void)
{
    HWINSTA h;
    DWORD len;
    WCHAR *name;
    static union {
        void *p;
        FARPROC f;
    } _OPENSSL_isservice = {
        NULL
    };

    if (_OPENSSL_isservice.p == NULL) {
        HANDLE mod = GetModuleHandle(NULL);
        FARPROC f = NULL;

        if (mod != NULL)
            f = GetProcAddress(mod, "_OPENSSL_isservice");
        if (f == NULL)
            _OPENSSL_isservice.p = (void *)-1;
        else
            _OPENSSL_isservice.f = f;
    }

    if (_OPENSSL_isservice.p != (void *)-1)
        return (int)((*_OPENSSL_isservice.f)());

    h = GetProcessWindowStation();
    if (h == NULL)
        return -1;

    if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        return -1;

    if (len > 512)
        return -1; /* paranoia */
    len++, len &= ~1; /* paranoia */
    name = (WCHAR *)alloca(len + sizeof(WCHAR));
    if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
        return -1;

    len++, len &= ~1; /* paranoia */
    name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
#if 1
    /*
     * This doesn't cover "interactive" services [working with real
     * WinSta0's] nor programs started non-interactively by Task Scheduler
     * [those are working with SAWinSta].
     */
    if (wcsstr(name, L"Service-0x"))
        return 1;
#else
    /* This covers all non-interactive programs such as services. */
    if (!wcsstr(name, L"WinSta0"))
        return 1;
#endif
    else
        return 0;
}
#endif
#else
int OPENSSL_isservice(void)
{
    return 0;
}
#endif

void OPENSSL_showfatal(const char *fmta, ...)
{
    va_list ap;
    TCHAR buf[256];
    const TCHAR *fmt;
    /*
     * First check if it's a console application, in which case the
     * error message would be printed to standard error.
     * Windows CE does not have a concept of a console application,
     * so we need to guard the check.
     */
#ifdef STD_ERROR_HANDLE
    HANDLE h;

    if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL && GetFileType(h) != FILE_TYPE_UNKNOWN) {
        /* must be console application */
        int len;
        DWORD out;

        va_start(ap, fmta);
        len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
        WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD)len, &out, NULL);
        va_end(ap);
        return;
    }
#endif

    if (sizeof(TCHAR) == sizeof(char))
        fmt = (const TCHAR *)fmta;
    else
        do {
            int keepgoing;
            size_t len_0 = strlen(fmta) + 1, i;
            WCHAR *fmtw;

            fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
            if (fmtw == NULL) {
                fmt = (const TCHAR *)L"no stack?";
                break;
            }
            if (!MultiByteToWideChar(CP_ACP, 0, fmta, (int)len_0, fmtw, (int)len_0))
                for (i = 0; i < len_0; i++)
                    fmtw[i] = (WCHAR)fmta[i];
            for (i = 0; i < len_0; i++) {
                if (fmtw[i] == L'%')
                    do {
                        keepgoing = 0;
                        switch (fmtw[i + 1]) {
                        case L'0':
                        case L'1':
                        case L'2':
                        case L'3':
                        case L'4':
                        case L'5':
                        case L'6':
                        case L'7':
                        case L'8':
                        case L'9':
                        case L'.':
                        case L'*':
                        case L'-':
                            i++;
                            keepgoing = 1;
                            break;
                        case L's':
                            fmtw[i + 1] = L'S';
                            break;
                        case L'S':
                            fmtw[i + 1] = L's';
                            break;
                        case L'c':
                            fmtw[i + 1] = L'C';
                            break;
                        case L'C':
                            fmtw[i + 1] = L'c';
                            break;
                        }
                    } while (keepgoing);
            }
            fmt = (const TCHAR *)fmtw;
        } while (0);

    va_start(ap, fmta);
    _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap);
    buf[OSSL_NELEM(buf) - 1] = _T('\0');
    va_end(ap);

#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0333
#ifdef OPENSSL_SYS_WIN_CORE
    /* ONECORE is always NONGUI and NT >= 0x0601 */
#if !defined(NDEBUG)
    /*
     * We are in a situation where we tried to report a critical
     * error and this failed for some reason. As a last resort,
     * in debug builds, send output to the debugger or any other
     * tool like DebugView which can monitor the output.
     */
    OutputDebugString(buf);
#endif
#else
    /* this -------------v--- guards NT-specific calls */
    if (check_winnt() && OPENSSL_isservice() > 0) {
        HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));

        if (hEventLog != NULL) {
            const TCHAR *pmsg = buf;

            if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
                    1, 0, &pmsg, NULL)) {
#if !defined(NDEBUG)
                /*
                 * We are in a situation where we tried to report a critical
                 * error and this failed for some reason. As a last resort,
                 * in debug builds, send output to the debugger or any other
                 * tool like DebugView which can monitor the output.
                 */
                OutputDebugString(pmsg);
#endif
            }

            (void)DeregisterEventSource(hEventLog);
        }
    } else {
        MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
    }
#endif
#else
    MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
#endif
}
#else
void OPENSSL_showfatal(const char *fmta, ...)
{
#ifndef OPENSSL_NO_STDIO
    va_list ap;

    va_start(ap, fmta);
    vfprintf(stderr, fmta, ap);
    va_end(ap);
#endif
}

int OPENSSL_isservice(void)
{
    return 0;
}
#endif

void OPENSSL_die(const char *message, const char *file, int line)
{
    OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",
        file, line, message);
#if !defined(_WIN32) || defined(OPENSSL_SYS_UEFI)
    abort();
#else
    /*
     * Win32 abort() customarily shows a dialog, but we just did that...
     */
#if !defined(_WIN32_WCE)
    raise(SIGABRT);
#endif
    _exit(3);
#endif
}

#if defined(__TANDEM) && defined(OPENSSL_VPROC)
/*
 * Define a VPROC function for HP NonStop build crypto library.
 * This is used by platform version identification tools.
 * Do not inline this procedure or make it static.
 */
#define OPENSSL_VPROC_STRING_(x) x##_CRYPTO
#define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x)
#define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC)
void OPENSSL_VPROC_FUNC(void) { }
#endif /* __TANDEM */
