int tlsio_schannel_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value)
{
    int result;

    if (tls_io == NULL || optionName == NULL)
    {
        result = __LINE__;
    }
    else
    {
        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
        /*x509certificate and x509privatekey are "referenced" by this layer*/
        if (strcmp("x509certificate", optionName) == 0)
        {
            if (tls_io_instance->x509certificate != NULL)
            {
                LogError("unable to set x509 options more than once");
                result =__LINE__;
            }
            else
            {
				tls_io_instance->x509certificate = (const char *)tlsio_schannel_CloneOption("x509certificate", value);
                if (tls_io_instance->x509privatekey != NULL)
                {
                    tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey);
                    if (tls_io_instance->x509_schannel_handle == NULL)
                    {
                        LogError("x509_schannel_create failed");
                        result = __LINE__;
                    }
                    else
                    {
                        /*all is fine, the x509 shall be used later*/
                        result = 0;
                    }
                }
                else
                {
                    result = 0; /*all is fine, maybe x509 privatekey will come and then x509 is set*/
                }
            }
        }
        else if (strcmp("x509privatekey", optionName) == 0)
        {
            if (tls_io_instance->x509privatekey != NULL)
            {
                LogError("unable to set more than once x509 options");
                result = __LINE__;
            }
            else
            {
				tls_io_instance->x509privatekey = (const char *)tlsio_schannel_CloneOption("x509privatekey", value);
                if (tls_io_instance->x509certificate!= NULL)
                {
                    tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey);
                    if (tls_io_instance->x509_schannel_handle == NULL)
                    {
                        LogError("x509_schannel_create failed");
                        result = __LINE__;
                    }
                    else
                    {
                        /*all is fine, the x509 shall be used later*/
                        result = 0;
                    }
                }
                else
                {
                    result = 0; /*all is fine, maybe x509 privatekey will come and then x509 is set*/
                }
            }
        }
        else if (tls_io_instance->socket_io == NULL)
        {
            result = __LINE__;
        }
        else
        {
            result = xio_setoption(tls_io_instance->socket_io, optionName, value);
        }
    }

    return result;
}
HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, const void* value)
{
    HTTPAPI_RESULT result;
    if (
        (handle == NULL) ||
        (optionName == NULL) ||
        (value == NULL)
        )
    {
        result = HTTPAPI_INVALID_ARG;
        LogError("invalid parameter (NULL) passed to HTTPAPI_SetOption");
    }
    else
    {
        HTTP_HANDLE_DATA* httpHandleData = (HTTP_HANDLE_DATA*)handle;
        if (strcmp(OPTION_HTTP_TIMEOUT, optionName) == 0)
        {
            long timeout = (long)(*(unsigned int*)value);
            httpHandleData->timeout = timeout;
            result = HTTPAPI_OK;
        }
        else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0)
        {
            httpHandleData->x509certificate = (const char*)value;
            if (httpHandleData->x509privatekey != NULL)
            {
                httpHandleData->x509SchannelHandle = x509_schannel_create(httpHandleData->x509certificate, httpHandleData->x509privatekey);
                if (httpHandleData->x509SchannelHandle == NULL)
                {
                    LogError("unable to x509_schannel_create");
                    result = HTTPAPI_ERROR;
                }
                else
                {
                    result = HTTPAPI_OK;
                }
            }
            else
            {
                /*if certificate comes 1st and private key is not set yet, then return OK and wait for the private key to be set*/
                result = HTTPAPI_OK;
            }
        }
        else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0)
        {
            httpHandleData->x509privatekey = (const char*)value;
            if (httpHandleData->x509certificate != NULL)
            {
                httpHandleData->x509SchannelHandle = x509_schannel_create(httpHandleData->x509certificate, httpHandleData->x509privatekey);
                if (httpHandleData->x509SchannelHandle == NULL)
                {
                    LogError("unable to x509_schannel_create");
                    result = HTTPAPI_ERROR;
                }
                else
                {
                    result = HTTPAPI_OK;
                }
            }
            else
            {
                /*if privatekey comes 1st and certificate is not set yet, then return OK and wait for the certificate to be set*/
                result = HTTPAPI_OK;
            }
        }
        else if (strcmp("TrustedCerts", optionName) == 0)
        {
            /*winhttp accepts all certificates, because it actually relies on the system ones*/
            result = HTTPAPI_OK;
        }
        else
        {
            result = HTTPAPI_INVALID_ARG;
            LogError("unknown option %s", optionName);
        }
    }
    return result;
}
int tls_server_io_schannel_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value)
{
    int result;

    if (tls_io == NULL || optionName == NULL)
    {
        LogError("invalid argument detected: CONCRETE_IO_HANDLE tls_io = %p, const char* optionName = %p", tls_io, optionName);
        result = __FAILURE__;
    }
    else
    {
        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
        if (strcmp("x509certificate", optionName) == 0)
        {
            if (tls_io_instance->x509certificate != NULL)
            {
                LogError("x509certificate has already been specified");
                result = __FAILURE__;
            }
            else
            {
                tls_io_instance->x509certificate = (char *)tls_server_io_schannel_CloneOption("x509certificate", value);
                if (tls_io_instance->x509certificate == NULL)
                {
                    LogError("tls_server_io_schannel_CloneOption failed");
                    result = __FAILURE__;
                }
                else
                {
                    if (tls_io_instance->x509privatekey != NULL)
                    {
                        tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey);
                        if (tls_io_instance->x509_schannel_handle == NULL)
                        {
                            LogError("x509_schannel_create failed");
                            result = __FAILURE__;
                        }
                        else
                        {
                            /*all is fine, the x509 shall be used later*/
                            result = 0;
                        }
                    }
                    else
                    {
                        result = 0; /*all is fine, maybe x509 privatekey will come and then x509 is set*/
                    }
                }
            }
        }
        else if (strcmp("x509privatekey", optionName) == 0)
        {
            if (tls_io_instance->x509privatekey != NULL)
            {
                LogError("x509privatekey has already been specified");
                result = __FAILURE__;
            }
            else
            {
                tls_io_instance->x509privatekey = (char *)tls_server_io_schannel_CloneOption("x509privatekey", value);
                if (tls_io_instance->x509privatekey == NULL)
                {
                    LogError("tls_server_io_schannel_CloneOption failed");
                    result = __FAILURE__;
                }
                else
                {
                    if (tls_io_instance->x509certificate != NULL)
                    {
                        tls_io_instance->x509_schannel_handle = x509_schannel_create(tls_io_instance->x509certificate, tls_io_instance->x509privatekey);
                        if (tls_io_instance->x509_schannel_handle == NULL)
                        {
                            LogError("x509_schannel_create failed");
                            result = __FAILURE__;
                        }
                        else
                        {
                            /*all is fine, the x509 shall be used later*/
                            result = 0;
                        }
                    }
                    else
                    {
                        result = 0; /*all is fine, maybe x509 cert will come and then x509 is set*/
                    }
                }
            }
        }
        else if (tls_io_instance->socket_io == NULL)
        {
            LogError("tls_io_instance->socket_io is not set");
            result = __FAILURE__;
        }
        else
        {
            result = xio_setoption(tls_io_instance->socket_io, optionName, value);
        }
    }

    return result;
}