/*
 * Copyright 1995-2025 The OpenSSL Project Authors. 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 <stdio.h>
#include <openssl/opensslv.h>
#include "internal/thread_once.h"
#include "internal/cryptlib.h"
#include "internal/e_os.h"

#if defined(_WIN32) && defined(OSSL_WINCTX)

#define TOSTR(x) #x
#define MAKESTR(x) TOSTR(x)
#define NOQUOTE(x) x
#if defined(OSSL_WINCTX)
#define REGISTRY_KEY "SOFTWARE\\WOW6432Node\\OpenSSL" \
                     "-" MAKESTR(OPENSSL_VERSION_MAJOR) "." MAKESTR(OPENSSL_VERSION_MINOR) "-" MAKESTR(OSSL_WINCTX)
#endif

/**
 * @brief The directory where OpenSSL is installed.
 */
static char openssldir[MAX_PATH + 1];

/**
 * @brief The pointer to the openssldir buffer
 */
static char *openssldirptr = NULL;

/**
 * @brief The directory where OpenSSL modules are located.
 */
static char modulesdir[MAX_PATH + 1];

/**
 * @brief The pointer to the modulesdir buffer
 */
static char *modulesdirptr = NULL;

/**
 * @brief Get the list of Windows registry directories.
 *
 * This function retrieves a list of Windows registry directories.
 *
 * @return A pointer to a char array containing the registry directories.
 */
static char *get_windows_regdirs(char *dst, DWORD dstsizebytes, LPCWSTR valuename)
{
    char *retval = NULL;
#ifdef REGISTRY_KEY
    DWORD keysizebytes;
    DWORD ktype;
    HKEY hkey;
    LSTATUS ret;
    DWORD index = 0;
    LPCWSTR tempstr = NULL;

    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        TEXT(REGISTRY_KEY), KEY_WOW64_32KEY,
        KEY_QUERY_VALUE, &hkey);
    if (ret != ERROR_SUCCESS)
        goto out;

    /* Always use wide call so we can avoid extra encoding conversions on the output */
    ret = RegQueryValueExW(hkey, valuename, NULL, &ktype, NULL,
        &keysizebytes);
    if (ret != ERROR_SUCCESS)
        goto out;
    if (ktype != REG_EXPAND_SZ && ktype != REG_SZ)
        goto out;
    if (keysizebytes > MAX_PATH * sizeof(WCHAR))
        goto out;

    /*
     * RegQueryValueExW does not guarantee the buffer is null terminated,
     * so we make space for one in the allocation
     */
    tempstr = OPENSSL_zalloc(keysizebytes + sizeof(WCHAR));

    if (tempstr == NULL)
        goto out;

    if (RegQueryValueExW(hkey, valuename,
            NULL, &ktype, (LPBYTE)tempstr, &keysizebytes)
        != ERROR_SUCCESS)
        goto out;

    if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, dstsizebytes,
            NULL, NULL))
        goto out;

    retval = dst;
out:
    OPENSSL_free(tempstr);
    RegCloseKey(hkey);
#endif /* REGISTRY_KEY */
    return retval;
}

static CRYPTO_ONCE defaults_setup_init = CRYPTO_ONCE_STATIC_INIT;

/**
 * @brief Function to setup default values to run once.
 * Only used in Windows environments.  Does run time initialization
 * of openssldir/modulesdir/enginesdir from the registry
 */
DEFINE_RUN_ONCE_STATIC(do_defaults_setup)
{
    get_windows_regdirs(openssldir, sizeof(openssldir), L"OPENSSLDIR");
    get_windows_regdirs(modulesdir, sizeof(modulesdir), L"MODULESDIR");

    /*
     * Set our pointers only if the directories are fetched properly
     */
    if (strlen(openssldir) > 0)
        openssldirptr = openssldir;

    if (strlen(modulesdir) > 0)
        modulesdirptr = modulesdir;

    return 1;
}
#endif /* defined(_WIN32) && defined(OSSL_WINCTX) */

/**
 * @brief Get the directory where OpenSSL is installed.
 *
 * @return A pointer to a string containing the OpenSSL directory path.
 */
const char *ossl_get_openssldir(void)
{
#if defined(_WIN32) && defined(OSSL_WINCTX)
    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
        return NULL;
    return (const char *)openssldirptr;
#else
    return OPENSSLDIR;
#endif
}

/**
 * @brief Get the directory where OpenSSL modules are located.
 *
 * @return A pointer to a string containing the modules directory path.
 */
const char *ossl_get_modulesdir(void)
{
#if defined(_WIN32) && defined(OSSL_WINCTX)
    if (!RUN_ONCE(&defaults_setup_init, do_defaults_setup))
        return NULL;
    return (const char *)modulesdirptr;
#else
    return MODULESDIR;
#endif
}

/**
 * @brief Get the build time defined windows installer context
 *
 * @return A char pointer to a string representing the windows install context
 */
const char *ossl_get_wininstallcontext(void)
{
#if defined(_WIN32) && defined(OSSL_WINCTX)
    return MAKESTR(OSSL_WINCTX);
#else
    return "Undefined";
#endif
}
