 +    return(refqt_ret);
 +}
 +
++quote3_error_t ECDSA256Quote::set_quote_config(const sgx_ql_config_t *config)
++{
++    quote3_error_t refqt_ret = SGX_QL_ERROR_UNEXPECTED;
++    int rc = 0;
++
++    rc = se_mutex_lock(&g_ql_global_data.m_enclave_load_mutex);
++    if (0 == rc) {
++        SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n");
++        return SGX_QL_ERROR_UNEXPECTED;
++    }
++
++    free_quote_config(g_ql_global_data.m_quote_config);
++
++    g_ql_global_data.m_quote_config =
++        (sgx_ql_config_t *)malloc(sizeof(sgx_ql_config_t));
++    if (NULL == g_ql_global_data.m_quote_config) {
++        refqt_ret = SGX_QL_ERROR_OUT_OF_MEMORY;
++        goto CLEANUP;
++    }
++
++    memcpy(g_ql_global_data.m_quote_config, config, sizeof(*config));
++    if (NULL == config->p_cert_data) {
++        g_ql_global_data.m_quote_config->p_cert_data = NULL;
++    } else {
++        g_ql_global_data.m_quote_config->p_cert_data =
++            (uint8_t *)malloc(config->cert_data_size);
++        if (NULL == g_ql_global_data.m_quote_config->p_cert_data) {
++            refqt_ret = SGX_QL_ERROR_OUT_OF_MEMORY;
++            goto CLEANUP;
++        }
++        memcpy(g_ql_global_data.m_quote_config->p_cert_data,
++               config->p_cert_data, config->cert_data_size);
++    }
++
++    refqt_ret = SGX_QL_SUCCESS;
++    CLEANUP:
++    rc = se_mutex_unlock(&g_ql_global_data.m_enclave_load_mutex);
++    if (0 == rc) {
++        SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex.\n");
++        refqt_ret = SGX_QL_ERROR_UNEXPECTED;
++    }
++
++    return(refqt_ret);
++}
+ 
  /**
   * This is the ECDSA-P256 specific init quote code.  The generic quote interfaces have been converted/reduced to the ECDSA specific inputs.
-  * The method will generate a new key and certify it when needed.
 diff -Nur -x '*.png' -x '*.gif' -x .gitignore QuoteGeneration/quote_wrapper/quote/sgx_ql_core_wrapper.cpp QuoteGeneration/quote_wrapper/quote/sgx_ql_core_wrapper.cpp
 --- QuoteGeneration/quote_wrapper/quote/sgx_ql_core_wrapper.cpp
 +++ QuoteGeneration/quote_wrapper/quote/sgx_ql_core_wrapper.cpp

  * Added sgx_qe_set_enclave_dirpath to set the directory paths for both the
    PCE and QE.
  * Removed duplicated code in qe_logic.cpp.
--
diff -Nur -x '*.png' -x '*.gif' -x .gitignore QuoteGeneration/common/inc/internal/se_map.h QuoteGeneration/common/inc/internal/se_map.h
--- QuoteGeneration/common/inc/internal/se_map.h

-    #else
-    HINSTANCE handle;
-    #endif
+    bool unlock_on_cleanup = false;
 
     if((NULL == p_pck_cert_id) ||
        (NULL == p_cert_cpu_svn) ||
@@ -259,175 +320,126 @@
         return SGX_QL_ERROR_INVALID_PARAMETER;
     }
 
-    #ifndef _MSC_VER
-    handle = dlopen(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME, RTLD_LAZY);
-    if (NULL == handle)
-    {
-        ///TODO:
-        // This is a temporary solution to make sure the legacy library without a version suffix can be loaded.
-        // We shalll remove this when we have a major version change later and drop the backward compatible
-        // support for old lib name.
-        #ifndef DISABLE_TRACE
-        old_libname_used = true;
-        #endif
-        handle = dlopen(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY, RTLD_LAZY);
+    if (!se_mutex_lock(&g_ql_global_data.m_enclave_load_mutex)) {
+        SE_TRACE(SE_TRACE_ERROR, "Failed to lock mutex\n");
+        return SGX_QL_ERROR_UNEXPECTED;
     }
-    if (handle) {
-        SE_TRACE(SE_TRACE_DEBUG, "Found the Quote's dependent library. %s.\n",
-            old_libname_used ? SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY : SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME);
-        p_sgx_get_quote_config = (sgx_get_quote_config_func_t)dlsym(handle, "sgx_ql_get_quote_config");
-        error1 = dlerror();
-        p_sgx_free_quote_config = (sgx_free_quote_config_func_t)dlsym(handle, "sgx_ql_free_quote_config");
-        error2 = dlerror();
-
-        if ((NULL == error1) &&
-             (NULL != p_sgx_get_quote_config) &&
-            (NULL == error2) &&
-             (NULL != p_sgx_free_quote_config)){
-            SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_ql_get_quote_config and sgx_ql_free_quote_config API.\n");
-            SE_TRACE(SE_TRACE_DEBUG, "Request the Quote Config data.\n");
-            ret_val = p_sgx_get_quote_config(p_pck_cert_id, &p_pck_cert_config);
-            if (SGX_QL_SUCCESS != ret_val) {
-                SE_TRACE(SE_TRACE_ERROR, "Error returned from the p_sgx_get_quote_config API. 0x%04x\n", ret_val);
-                ret_val = SGX_QL_NO_PLATFORM_CERT_DATA;
-                goto CLEANUP;
-            }
-            if(NULL == p_pck_cert_config) {
-                ret_val = SGX_QL_NO_PLATFORM_CERT_DATA;
-                SE_TRACE(SE_TRACE_ERROR, "p_sgx_get_quote_config returned NULL for p_pck_cert_config.\n");
-                goto CLEANUP;
-            }
-            if(p_pck_cert_config->version != SGX_QL_CONFIG_VERSION_1) {
-                SE_TRACE(SE_TRACE_ERROR, "p_sgx_get_quote_config returned incompatible pck_cert_config version.\n");
-                ret_val = SGX_QL_NO_PLATFORM_CERT_DATA;
-                goto CLEANUP;
-            }
-            if(0 != memcpy_s(p_cert_cpu_svn, sizeof(*p_cert_cpu_svn), &p_pck_cert_config->cert_cpu_svn, sizeof(p_pck_cert_config->cert_cpu_svn))) {
-                ret_val = SGX_QL_ERROR_UNEXPECTED;
-                goto CLEANUP;
-            }
-            *p_cert_pce_isv_svn = p_pck_cert_config->cert_pce_isv_svn;
-            if(NULL == p_cert_data) {
-                // The caller only needs the TCBm and/or the required buffer size.
-                // Return the required buffer size.
-                *p_cert_data_size = p_pck_cert_config->cert_data_size;
-            }
-            else {
-                // The caller wants the TCBm and the required buffer size.
-                if(*p_cert_data_size < p_pck_cert_config->cert_data_size) {
-                    // The buffer passed in to this API is not large enouge to contain the provider library's returned cert data.
-                    // This shouldn't happen since the passed in value should be the result of calling this function
-                    // with the inputted p_cert_data equal to NULL just befor this caller.
-                    SE_TRACE(SE_TRACE_ERROR, "sgx_ql_get_quote_config returned a cert_data_size too large to fit in inputted buffer.\n");
-                    ret_val = SGX_QL_ERROR_INVALID_PARAMETER;
-                    goto CLEANUP;
-                }
-                if(NULL == p_pck_cert_config->p_cert_data) {
-                    SE_TRACE(SE_TRACE_ERROR, "sgx_ql_get_quote_config returned NULL for p_cert_data.\n");
+
+    if (NULL != g_ql_global_data.m_quote_config) {
+        SE_TRACE(SE_TRACE_DEBUG, "Using explicitly set quote config.\n");
+        p_pck_cert_config = g_ql_global_data.m_quote_config;
+        unlock_on_cleanup = true;
+    } else {
+        // If the quote config was not explicitly set, try to look up the config
+        // using a Platform Quote Provider Library.
+
+        // Don't hold the lock if we're calling out to an unknown library.
+        unlock_on_cleanup = false;
+        if (!se_mutex_unlock(&g_ql_global_data.m_enclave_load_mutex)) {
+            SE_TRACE(SE_TRACE_ERROR, "Failed to unlock mutex\n");
+        }
+
+        handle = load_library(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME);
+        if (NULL == handle && NULL != SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY)
+        {
+            // This is a temporary solution to make sure the legacy library without a version suffix can be loaded.
+            // We shalll remove this when we have a major version change later and drop the backward compatible
+            // support for old lib name.
+            old_libname_used = true;
+            handle = load_library(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY);
+        }
+        if (handle) {
+            SE_TRACE(SE_TRACE_DEBUG, "Found the Quote's dependent library. %s.\n",
+                old_libname_used ? SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME_LEGACY : SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME);
+            p_sgx_get_quote_config = (sgx_get_quote_config_func_t)lookup_symbol(handle, "sgx_ql_get_quote_config");
+            error1 = get_lookup_error();
+            p_sgx_free_quote_config = (sgx_free_quote_config_func_t)lookup_symbol(handle, "sgx_ql_free_quote_config");
+            error2 = get_lookup_error();
+
+            if ((NULL == error1) &&
+                 (NULL != p_sgx_get_quote_config) &&
+                (NULL == error2) &&
+                 (NULL != p_sgx_free_quote_config)){
+                SE_TRACE(SE_TRACE_DEBUG, "Found the sgx_ql_get_quote_config and sgx_ql_free_quote_config API.\n");
+                SE_TRACE(SE_TRACE_DEBUG, "Request the Quote Config data.\n");
+                ret_val = p_sgx_get_quote_config(p_pck_cert_id, &p_pck_cert_config);
+                if (SGX_QL_SUCCESS != ret_val) {
+                    SE_TRACE(SE_TRACE_ERROR, "Error returned from the p_sgx_get_quote_config API. 0x%04x\n", ret_val);
                     ret_val = SGX_QL_NO_PLATFORM_CERT_DATA;
                     goto CLEANUP;
                 }
-                // Copy the returned cert data
-                if(0 != memcpy_s(p_cert_data, *p_cert_data_size, p_pck_cert_config->p_cert_data, p_pck_cert_config->cert_data_size)) {
-                    ret_val = SGX_QL_ERROR_UNEXPECTED;
-                    goto CLEANUP;
-                }
-                // Return the number of bytes copied.
-                *p_cert_data_size = p_pck_cert_config->cert_data_size;
+            } else {
+                ret_val = SGX_QL_PLATFORM_LIB_UNAVAILABLE;
+                SE_TRACE(SE_TRACE_WARNING, "Couldn't find 'sgx_ql_get_quote_config()' and 'sgx_ql_free_quote_config()' in the platform library. %s\n", dlerror());
+                goto CLEANUP;
             }
         } else {
-            SE_TRACE(SE_TRACE_WARNING, "Couldn't find 'sgx_ql_get_quote_config()' and 'sgx_ql_free_quote_config()' in the platform library. %s\n", dlerror());
+            ret_val = SGX_QL_PLATFORM_LIB_UNAVAILABLE;
+            SE_TRACE(SE_TRACE_DEBUG, "Couldn't find the platform library. %s\n", dlerror());
+            goto CLEANUP;
         }
-    } else {
-        SE_TRACE(SE_TRACE_DEBUG, "Couldn't find the platform library. %s\n", dlerror());
     }
 
-    CLEANUP:
-    if(NULL != p_sgx_free_quote_config){
-        if(NULL != p_pck_cert_config) {
-            p_sgx_free_quote_config(p_pck_cert_config);
-        }
+    if(NULL == p_pck_cert_config) {
+        ret_val = SGX_QL_NO_PLATFORM_CERT_DATA;
+        SE_TRACE(SE_TRACE_ERROR, "p_sgx_get_quote_config returned NULL for p_pck_cert_config.\n");
+        goto CLEANUP;
     }
-    if(NULL != handle) {
-        dlclose(handle);
+    if(p_pck_cert_config->version != SGX_QL_CONFIG_VERSION_1) {
+        SE_TRACE(SE_TRACE_ERROR, "p_sgx_get_quote_config returned incompatible pck_cert_config version.\n");
+        ret_val = SGX_QL_NO_PLATFORM_CERT_DATA;
+        goto CLEANUP;
     }
-    #else
-    handle = LoadLibrary(TEXT(SGX_QL_QUOTE_CONFIG_LIB_FILE_NAME));
-    if (handle != NULL) {
