src/configuration_reader.c (453 lines of code) (raw):

// Copyright (C) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include <inttypes.h> #include <stdlib.h> #include <stdbool.h> #include <wchar.h> #include <corecrt_math.h> #include "windows.h" #include "macro_utils/macro_utils.h" #include "c_logging/logger.h" #include "c_pal/gballoc_hl.h" #include "c_pal/gballoc_hl_redirect.h" #include "c_pal/string_utils.h" #include "sf_c_util/hresult_to_string.h" #include "sf_c_util/configuration_reader.h" #define TRUEString L"True" #define FALSEString L"False" static int get_string_value_from_package(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, IFabricConfigurationPackage** fabric_configuration_package, const wchar_t** wchar_value) { int result; HRESULT hr; /*Codes_SRS_CONFIGURATION_READER_01_006: [ configuration_reader_get_uint8_t shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_017: [ configuration_reader_get_uint32_t shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_006: [ configuration_reader_get_uint64_t shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_22_006: [ configuration_reader_get_double shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_028: [ configuration_reader_get_char_string shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_038: [ configuration_reader_get_wchar_string shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_048: [ configuration_reader_get_thandle_rc_string shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ hr = activation_context->lpVtbl->GetConfigurationPackage(activation_context, config_package_name, fabric_configuration_package); if (FAILED(hr)) { /*Codes_SRS_CONFIGURATION_READER_01_010: [ If there are any other failures then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_021: [ If there are any other failures then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_010: [ If there are any other failures then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_22_010: [ If there are any other failures then configuration_reader_get_double shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_031: [ If there are any other failures then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_041: [ If there are any other failures then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_052: [ If there are any other failures then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ LogHRESULTError(hr, "GetConfigurationPackage failed (config_package_name:%ls)", config_package_name); result = MU_FAILURE; } else { BOOLEAN is_encrypted = FALSE; /*Codes_SRS_CONFIGURATION_READER_01_007: [ configuration_reader_get_uint8_t shall call GetValue on the configuration package with section_name and parameter_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_018: [ configuration_reader_get_uint32_t shall call GetValue on the configuration package with section_name and parameter_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_007: [ configuration_reader_get_uint64_t shall call GetValue on the configuration package with section_name and parameter_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_22_007: [ configuration_reader_get_double shall call GetValue on the configuration package with section_name and parameter_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_029: [ configuration_reader_get_char_string shall call GetValue on the configuration package with section_name and parameter_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_039: [ configuration_reader_get_wchar_string shall call GetValue on the configuration package with section_name and parameter_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_049: [ configuration_reader_get_thandle_rc_string shall call GetValue on the configuration package with section_name and parameter_name. ]*/ hr = (*fabric_configuration_package)->lpVtbl->GetValue((*fabric_configuration_package), section_name, parameter_name, &is_encrypted, wchar_value); if (FAILED(hr)) { /*Codes_SRS_CONFIGURATION_READER_01_010: [ If there are any other failures then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_021: [ If there are any other failures then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_010: [ If there are any other failures then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_22_010: [ If there are any other failures then configuration_reader_get_double shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_031: [ If there are any other failures then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_041: [ If there are any other failures then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ /*Codes_SRS_CONFIGURATION_READER_42_052: [ If there are any other failures then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ LogHRESULTError(hr, "GetValue failed (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { result = 0; goto all_ok; } (void)(*fabric_configuration_package)->lpVtbl->Release(*fabric_configuration_package); *fabric_configuration_package = NULL; } all_ok: return result; } int configuration_reader_get_uint8_t(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, uint8_t* value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_01_001: [ If activation_context is NULL then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_01_002: [ If config_package_name is NULL or empty then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_01_003: [ If section_name is NULL or empty then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_01_004: [ If parameter_name is NULL or empty then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_01_005: [ If value is NULL then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, uint8_t* value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_01_008: [ configuration_reader_get_uint8_t shall convert the value to uint8_t and store it in value. ]*/ wchar_t* end_ptr; uint64_t temp = wcstoull(wchar_value, &end_ptr, 10); if (end_ptr == wchar_value) { /*Codes_SRS_CONFIGURATION_READER_42_021: [ If there are any other failures then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ LogError("failure in wcstoull(%ls): subject sequence is empty or does not have the expected form (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { if ((temp == ULLONG_MAX) && (errno == ERANGE)) { /*Codes_SRS_CONFIGURATION_READER_01_009: [ If the value is outside the range of representable values then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ LogError("ULLONGMAX was returned for wcstoull(%ls), indicating the correct value is outside the range of representable values (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else if (temp > UINT8_MAX) { /*Codes_SRS_CONFIGURATION_READER_01_009: [ If the value is outside the range of representable values then configuration_reader_get_uint8_t shall fail and return a non-zero value. ]*/ LogError("The value %" PRIu64 " is too large for uint8_t (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", temp, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_01_011: [ configuration_reader_get_uint8_t shall succeed and return 0. ]*/ *value = (uint8_t)temp; result = 0; } } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; } int configuration_reader_get_uint32_t(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, uint32_t* value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_42_012: [ If activation_context is NULL then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_42_013: [ If config_package_name is NULL or empty then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_014: [ If section_name is NULL or empty then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_015: [ If parameter_name is NULL or empty then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_016: [ If value is NULL then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, uint32_t* value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_019: [ configuration_reader_get_uint32_t shall convert the value to uint32_t and store it in value. ]*/ wchar_t* end_ptr; uint64_t temp = wcstoull(wchar_value, &end_ptr, 10); if (end_ptr == wchar_value) { /*Codes_SRS_CONFIGURATION_READER_42_021: [ If there are any other failures then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ LogError("failure in wcstoull(%ls): subject sequence is empty or does not have the expected form (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { if ((temp == ULLONG_MAX) && (errno == ERANGE)) { /*Codes_SRS_CONFIGURATION_READER_42_020: [ If the value is outside the range of representable values then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ LogError("ULLONGMAX was returned for wcstoull(%ls), indicating the correct value is outside the range of representable values (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else if (temp > UINT32_MAX) { /*Codes_SRS_CONFIGURATION_READER_42_020: [ If the value is outside the range of representable values then configuration_reader_get_uint32_t shall fail and return a non-zero value. ]*/ LogError("The value %" PRIu64 " is too large for uint32_t (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", temp, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_022: [ configuration_reader_get_uint32_t shall succeed and return 0. ]*/ *value = (uint32_t)temp; result = 0; } } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; } int configuration_reader_get_uint64_t(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, uint64_t* value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_42_001: [ If activation_context is NULL then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_42_002: [ If config_package_name is NULL or empty then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_003: [ If section_name is NULL or empty then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_004: [ If parameter_name is NULL or empty then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_005: [ If value is NULL then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, uint64_t* value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_008: [ configuration_reader_get_uint64_t shall convert the value to uint64_t and store it in value. ]*/ wchar_t* end_ptr; uint64_t temp = wcstoull(wchar_value, &end_ptr, 10); if (end_ptr == wchar_value) { /*Codes_SRS_CONFIGURATION_READER_42_010: [ If there are any other failures then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ LogError("failure in wcstoull(%ls): subject sequence is empty or does not have the expected form (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { if ((temp == ULLONG_MAX) && (errno == ERANGE)) { /*Codes_SRS_CONFIGURATION_READER_42_009: [ If the value is outside the range of representable values then configuration_reader_get_uint64_t shall fail and return a non-zero value. ]*/ LogError("ULLONGMAX was returned for wcstoull(%ls), indicating the correct value is outside the range of representable values (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_011: [ configuration_reader_get_uint64_t shall succeed and return 0. ]*/ *value = temp; result = 0; } } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; } int configuration_reader_get_double(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, double* value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_22_001: [ If activation_context is NULL then configuration_reader_get_double shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_22_002: [ If config_package_name is NULL or empty then configuration_reader_get_double shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_22_003: [ If section_name is NULL or empty then configuration_reader_get_double shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_22_004: [ If parameter_name is NULL or empty then configuration_reader_get_double shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_22_005: [ If value is NULL then configuration_reader_get_double shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, double* value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_22_008: [ configuration_reader_get_double shall convert the value to double and store it in value. ]*/ wchar_t* end_ptr; double temp = wcstod(wchar_value, &end_ptr); if (end_ptr == wchar_value) { /*Codes_SRS_CONFIGURATION_READER_22_010: [ If there are any other failures then configuration_reader_get_double shall fail and return a non-zero value. ]*/ LogError("failure in wcstod(%ls): subject sequence is empty or does not have the expected form (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { if (((temp == HUGE_VAL) || (temp == -HUGE_VAL)) && (errno == ERANGE)) { /*Codes_SRS_CONFIGURATION_READER_22_009: [ If the value is outside the range of representable values then configuration_reader_get_double shall fail and return a non-zero value. ]*/ LogError("HUGE_VAL was returned for wcstod(%ls), indicating the correct value is outside the range of representable values (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_22_011: [ configuration_reader_get_double shall succeed and return 0. ]*/ *value = temp; result = 0; } } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; } int configuration_reader_get_bool(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, bool* value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_03_001: [ If activation_context is NULL then configuration_reader_get_bool shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_03_002: [ If config_package_name is NULL or empty then configuration_reader_get_bool shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_03_003: [ If section_name is NULL or empty then configuration_reader_get_bool shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_03_004: [ If parameter_name is NULL or empty then configuration_reader_get_bool shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_03_005: [ If value is NULL then configuration_reader_get_bool shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, uint32_t* value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; /*Codes_SRS_CONFIGURATION_READER_03_006: [ configuration_reader_get_bool shall call the GetConfigurationPackage function on activation_context with config_package_name. ]*/ /*Codes_SRS_CONFIGURATION_READER_03_007: [ configuration_reader_get_bool shall call GetValue on the configuration package with section_name and parameter_name. ]*/ if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error /*Codes_SRS_CONFIGURATION_READER_03_011: [ If there are any other failures then configuration_reader_get_bool shall fail and return a non-zero value. ]*/ result = MU_FAILURE; } else { // Codes_SRS_CONFIGURATION_READER_11_001: [ configuration_reader_get_bool shall do a case insensitive comparison of the string. ] /*Codes_SRS_CONFIGURATION_READER_03_009: [ If the string is False, configuration_reader_get_bool shall set value to false and return 0. ]*/ /*Codes_SRS_CONFIGURATION_READER_03_012: [ configuration_reader_get_bool shall succeed and return 0. ]*/ if (_wcsicmp(wchar_value, FALSEString) == 0) { *value = false; result = 0; } /*Codes_SRS_CONFIGURATION_READER_03_010: [ If the string is True, configuration_reader_get_bool shall set value to true and return 0. ]*/ /*Codes_SRS_CONFIGURATION_READER_03_012: [ configuration_reader_get_bool shall succeed and return 0. ]*/ else if (_wcsicmp(wchar_value, TRUEString) == 0) { *value = true; result = 0; } /*Codes_SRS_CONFIGURATION_READER_03_014: [ If the string is an empty string, configuration_reader_get_bool shall set value to false and return 0. ]*/ else if (wcscmp(wchar_value, L"") == 0) { *value = false; result = 0; } else { /*Codes_SRS_CONFIGURATION_READER_03_013: [ If the string is anything other than the above, configuration_reader_get_bool shall fail and return a non-zero value. ]*/ LogError("Invalid boolean value %ls for const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; } int configuration_reader_get_char_string(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, char** value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_42_023: [ If activation_context is NULL then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_42_024: [ If config_package_name is NULL or empty then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_025: [ If section_name is NULL or empty then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_026: [ If parameter_name is NULL or empty then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_027: [ If value is NULL then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, char** value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_030: [ configuration_reader_get_char_string shall convert the value from a wide-character string to narrow-character string and store it in value. ]*/ char* temp = sprintf_char("%ls", wchar_value); if (temp == NULL) { /*Codes_SRS_CONFIGURATION_READER_42_031: [ If there are any other failures then configuration_reader_get_char_string shall fail and return a non-zero value. ]*/ LogError("Failed to copy string %ls (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_032: [ configuration_reader_get_char_string shall succeed and return 0. ]*/ *value = temp; result = 0; } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; } int configuration_reader_get_thandle_rc_string(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, THANDLE(RC_STRING)* value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_42_043: [ If activation_context is NULL then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_42_044: [ If config_package_name is NULL or empty then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_045: [ If section_name is NULL or empty then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_046: [ If parameter_name is NULL or empty then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_047: [ If value is NULL then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, THANDLE(RC_STRING)* value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_050: [ configuration_reader_get_thandle_rc_string shall convert the value from a wide-character string to narrow-character string. ]*/ char* temp = sprintf_char("%ls", wchar_value); if (temp == NULL) { /*Codes_SRS_CONFIGURATION_READER_42_052: [ If there are any other failures then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ LogError("Failed to copy string %ls (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_051: [ configuration_reader_get_thandle_rc_string shall store the converted string in a THANDLE(RC_STRING). ]*/ THANDLE(RC_STRING) temp_rc = rc_string_create_with_move_memory(temp); if (temp_rc == NULL) { /*Codes_SRS_CONFIGURATION_READER_42_052: [ If there are any other failures then configuration_reader_get_thandle_rc_string shall fail and return a non-zero value. ]*/ LogError("Failed to wrap string %s in RC_STRING (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", temp, config_package_name, section_name, parameter_name); result = MU_FAILURE; free(temp); } else { THANDLE_INITIALIZE_MOVE(RC_STRING)(value, &temp_rc); /*Codes_SRS_CONFIGURATION_READER_42_053: [ configuration_reader_get_thandle_rc_string shall succeed and return 0. ]*/ result = 0; } } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; } int configuration_reader_get_wchar_string(IFabricCodePackageActivationContext* activation_context, const wchar_t* config_package_name, const wchar_t* section_name, const wchar_t* parameter_name, wchar_t** value) { int result; if ( /*Codes_SRS_CONFIGURATION_READER_42_033: [ If activation_context is NULL then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ activation_context == NULL || /*Codes_SRS_CONFIGURATION_READER_42_034: [ If config_package_name is NULL or empty then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ (config_package_name == NULL || config_package_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_035: [ If section_name is NULL or empty then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ (section_name == NULL || section_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_036: [ If parameter_name is NULL or empty then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ (parameter_name == NULL || parameter_name[0] == L'\0') || /*Codes_SRS_CONFIGURATION_READER_42_037: [ If value is NULL then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ (value == NULL) ) { LogError("Invalid args: IFabricCodePackageActivationContext* activation_context = %p, const wchar_t* config_package_name = %ls, const wchar_t* section_name = %ls, const wchar_t* parameter_name = %ls, wchar_t** value = %p", activation_context, MU_WP_OR_NULL(config_package_name), MU_WP_OR_NULL(section_name), MU_WP_OR_NULL(parameter_name), value); result = MU_FAILURE; } else { IFabricConfigurationPackage* fabric_configuration_package; const wchar_t* wchar_value; if (get_string_value_from_package(activation_context, config_package_name, section_name, parameter_name, &fabric_configuration_package, &wchar_value) != 0) { // already logged error result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_040: [ configuration_reader_get_wchar_string shall copy the string and store it in value. ]*/ *value = sprintf_wchar(L"%s", wchar_value); if (*value == NULL) { /*Codes_SRS_CONFIGURATION_READER_42_041: [ If there are any other failures then configuration_reader_get_wchar_string shall fail and return a non-zero value. ]*/ LogError("Failed to copy string %ls (config_package_name:%ls, section_name:%ls, parameter_name:%ls)", wchar_value, config_package_name, section_name, parameter_name); result = MU_FAILURE; } else { /*Codes_SRS_CONFIGURATION_READER_42_042: [ configuration_reader_get_wchar_string shall succeed and return 0. ]*/ result = 0; } (void)fabric_configuration_package->lpVtbl->Release(fabric_configuration_package); } } return result; }