/*
 * 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
}
