Пример #1
0
/**
 * When the framework is not found, display detailed error message
 *   about available frameworks and installation of new framework.
 */
void handle_missing_framework_error(const pal::string_t& fx_name, const pal::string_t& fx_version, const pal::string_t& fx_dir)
{
    pal::string_t fx_ver_dirs = get_directory(fx_dir);

    // Display the error message about missing FX.
    trace::error(_X("The specified framework '%s', version '%s' was not found."), fx_name.c_str(), fx_version.c_str());
    trace::error(_X("  - Check application dependencies and target a framework version installed at:"));
    trace::error(_X("      %s"), fx_ver_dirs.c_str());

    // Gather the list of versions installed at the shared FX location.
    bool is_print_header = true;
    std::vector<pal::string_t> versions;
    pal::readdir(fx_ver_dirs, &versions);
    for (const auto& ver : versions)
    {
        // Make sure we filter out any non-version folders at shared FX location.
        fx_ver_t parsed(-1, -1, -1);
        if (fx_ver_t::parse(ver, &parsed, false))
        {
            // Print banner only once before printing the versions
            if (is_print_header)
            {
                trace::error(_X("  - The following versions are installed:"));
                is_print_header = false;
            }
            trace::error(_X("      %s"), ver.c_str());
        }
    }
    trace::error(_X("  - Alternatively, install the framework version '%s'."), fx_version.c_str());
}
Пример #2
0
bool starts_with(const pal::string_t& value, const pal::string_t& prefix, bool match_case)
{
    if (prefix.empty())
    {
        // Cannot start with an empty string.
        return false;
    }
    auto cmp = match_case ? pal::strncmp : pal::strncasecmp;
    return (value.size() >= prefix.size()) &&
        cmp(value.c_str(), prefix.c_str(), prefix.size()) == 0;
}
Пример #3
0
bool pal::touch_file(const pal::string_t& path)
{
    int fd = open(path.c_str(), (O_CREAT | O_EXCL), (S_IRUSR | S_IRGRP | S_IROTH));
    if (fd == -1)
    {
        trace::warning(_X("open(%s) failed in %s"), path.c_str(), _STRINGIFY(__FUNCTION__));
        return false;
    }
    (void) close(fd);
    return true;
}
Пример #4
0
bool pal::pal_utf8string(const pal::string_t& str, std::vector<char>* out)
{
    out->clear();

    // Pass -1 as we want explicit null termination in the char buffer.
    size_t size = ::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, nullptr, 0, nullptr, nullptr);
    if (size == 0)
    {
        return false;
    }
    out->resize(size, '\0');
    return ::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, out->data(), out->size(), nullptr, nullptr) != 0;
}
Пример #5
0
/**
 * Resolve the hostpolicy version from deps.
 *  - Scan the deps file's libraries section and find the hostpolicy version in the file.
 */
pal::string_t resolve_hostpolicy_version_from_deps(const pal::string_t& deps_json)
{
    trace::verbose(_X("--- Resolving %s version from deps json [%s]"), LIBHOSTPOLICY_NAME, deps_json.c_str());

    pal::string_t retval;
    if (!pal::file_exists(deps_json))
    {
        trace::verbose(_X("Dependency manifest [%s] does not exist"), deps_json.c_str());
        return retval;
    }

    pal::ifstream_t file(deps_json);
    if (!file.good())
    {
        trace::verbose(_X("Dependency manifest [%s] could not be opened"), deps_json.c_str());
        return retval;
    }

    if (skip_utf8_bom(&file))
    {
        trace::verbose(_X("UTF-8 BOM skipped while reading [%s]"), deps_json.c_str());
    }

    try
    {
        const auto root = json_value::parse(file);
        const auto& json = root.as_object();
        const auto& libraries = json.at(_X("libraries")).as_object();

        // Look up the root package instead of the "runtime" package because we can't do a full rid resolution.
        // i.e., look for "Microsoft.NETCore.DotNetHostPolicy/" followed by version.
        pal::string_t prefix = _X("Microsoft.NETCore.DotNetHostPolicy/");
        for (const auto& library : libraries)
        {
            if (starts_with(library.first, prefix, false))
            {
                // Extract the version information that occurs after '/'
                retval = library.first.substr(prefix.size());
                break;
            }
        }
    }
    catch (const std::exception& je)
    {
        pal::string_t jes;
        (void)pal::utf8_palstring(je.what(), &jes);
        trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), deps_json.c_str(), jes.c_str());
    }
    trace::verbose(_X("Resolved version %s from dependency manifest file [%s]"), retval.c_str(), deps_json.c_str());
    return retval;
}
Пример #6
0
int execute_app(
    const pal::string_t& impl_dll_dir,
    const corehost_init_t* init,
    const int argc,
    const pal::char_t* argv[])
{
    pal::dll_t corehost;
    corehost_main_fn host_main = nullptr;
    corehost_load_fn host_load = nullptr;
    corehost_unload_fn host_unload = nullptr;

    int code = load_host_library(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);

    if (code != StatusCode::Success)
    {
        trace::error(_X("Could not load host policy library [%s]"), impl_dll_dir.c_str());
        return code;
    }

    if ((code = host_load(init)) == 0)
    {
        code = host_main(argc, argv);
        (void)host_unload();
    }

    pal::unload_library(corehost);

    return code;
}
Пример #7
0
int load_host_library_common(
    const pal::string_t& lib_dir,
    pal::string_t& host_path,
    pal::dll_t* h_host,
    corehost_load_fn* load_fn,
    corehost_unload_fn* unload_fn)
{
    if (!library_exists_in_dir(lib_dir, LIBHOSTPOLICY_NAME, &host_path))
    {
        return StatusCode::CoreHostLibMissingFailure;
    }

    // Load library
    if (!pal::load_library(&host_path, h_host))
    {
        trace::info(_X("Load library of %s failed"), host_path.c_str());
        return StatusCode::CoreHostLibLoadFailure;
    }

    // Obtain entrypoint symbols
    *load_fn = (corehost_load_fn)pal::get_symbol(*h_host, "corehost_load");
    *unload_fn = (corehost_unload_fn)pal::get_symbol(*h_host, "corehost_unload");

    return (*load_fn != nullptr) && (*unload_fn != nullptr)
        ? StatusCode::Success
        : StatusCode::CoreHostEntryPointFailure;
}
Пример #8
0
/**
 * Given a directory and a version, find if the package relative
 *     dir under the given directory contains hostpolicy.dll
 */
bool to_hostpolicy_package_dir(const pal::string_t& dir, const pal::string_t& version, pal::string_t* candidate)
{
    assert(!version.empty());

    candidate->clear();

    // Ensure the relative dir contains platform directory separators.
    pal::string_t rel_dir = _STRINGIFY(HOST_POLICY_PKG_REL_DIR);
    if (DIR_SEPARATOR != '/')
    {
        replace_char(&rel_dir, '/', DIR_SEPARATOR);
    }

    // Construct the path to directory containing hostpolicy.
    pal::string_t path = dir;
    append_path(&path, _STRINGIFY(HOST_POLICY_PKG_NAME)); // package name
    append_path(&path, version.c_str());                  // package version
    append_path(&path, rel_dir.c_str());                  // relative dir containing hostpolicy library

    // Check if "path" contains the required library.
    if (!library_exists_in_dir(path, LIBHOSTPOLICY_NAME, nullptr))
    {
        trace::verbose(_X("Did not find %s in directory %s"), LIBHOSTPOLICY_NAME, path.c_str());
        return false;
    }

    // "path" contains the directory containing hostpolicy library.
    *candidate = path;

    trace::verbose(_X("Found %s in directory %s"), LIBHOSTPOLICY_NAME, path.c_str());
    return true;
}
Пример #9
0
// -----------------------------------------------------------------------------
// Load local assemblies by priority order of their file extensions and
// unique-fied  by their simple name.
//
void deps_resolver_t::get_dir_assemblies(
    const pal::string_t& dir,
    const pal::string_t& dir_name,
    dir_assemblies_t* dir_assemblies)
{
    trace::verbose(_X("Adding files from %s dir %s"), dir_name.c_str(), dir.c_str());

    // Managed extensions in priority order, pick DLL over EXE and NI over IL.
    const pal::string_t managed_ext[] = { _X(".ni.dll"), _X(".dll"), _X(".ni.exe"), _X(".exe") };

    // List of files in the dir
    std::vector<pal::string_t> files;
    pal::readdir(dir, &files);

    for (const auto& ext : managed_ext)
    {
        for (const auto& file : files)
        {
            // Nothing to do if file length is smaller than expected ext.
            if (file.length() <= ext.length())
            {
                continue;
            }

            auto file_name = file.substr(0, file.length() - ext.length());
            auto file_ext = file.substr(file_name.length());

            // Ext did not match expected ext, skip this file.
            if (pal::strcasecmp(file_ext.c_str(), ext.c_str()))
            {
                continue;
            }

            // Already added entry for this asset, by priority order skip this ext
            if (dir_assemblies->count(file_name))
            {
                trace::verbose(_X("Skipping %s because the %s already exists in %s assemblies"), file.c_str(), dir_assemblies->find(file_name)->second.c_str(), dir_name.c_str());
                continue;
            }

            // Add entry for this asset
            pal::string_t file_path = dir + DIR_SEPARATOR + file;
            trace::verbose(_X("Adding %s to %s assembly set from %s"), file_name.c_str(), dir_name.c_str(), file_path.c_str());
            dir_assemblies->emplace(file_name, file_path);
        }
    }
}
Пример #10
0
runtime_config_t::runtime_config_t(const pal::string_t& path)
    : m_fx_roll_fwd(true)
    , m_path(path)
    , m_portable(false)
{
    m_valid = ensure_parsed();
    trace::verbose(_X("Runtime config [%s] is valid=[%d]"), path.c_str(), m_valid);
} 
Пример #11
0
bool get_global_shared_store_dirs(std::vector<pal::string_t>*  dirs, const pal::string_t& arch, const pal::string_t& tfm)
{
    std::vector<pal::string_t> global_dirs;
    if (!pal::get_global_dotnet_dirs(&global_dirs))
    {
        return false;
    }

    for (pal::string_t dir : global_dirs)
    {
        append_path(&dir, RUNTIME_STORE_DIRECTORY_NAME);
        append_path(&dir, arch.c_str());
        append_path(&dir, tfm.c_str());
        dirs->push_back(dir);
    }
    return true;
}
Пример #12
0
// -----------------------------------------------------------------------------
// Load the deps file and parse its "entry" lines which contain the "fields" of
// the entry. Populate an array of these entries.
//
bool deps_json_t::load(bool portable, const pal::string_t& deps_path, const rid_fallback_graph_t& rid_fallback_graph)
{
    m_file_exists = pal::file_exists(deps_path);

    // If file doesn't exist, then assume parsed.
    if (!m_file_exists)
    {
        trace::verbose(_X("Could not locate the dependencies manifest file [%s]. Some libraries may fail to resolve."), deps_path.c_str());
        return true;
    }

    // Somehow the file stream could not be opened. This is an error.
    pal::ifstream_t file(deps_path);
    if (!file.good())
    {
        trace::error(_X("Could not open dependencies manifest file [%s]"), deps_path.c_str());
        return false;
    }

    if (skip_utf8_bom(&file))
    {
        trace::verbose(_X("UTF-8 BOM skipped while reading [%s]"), deps_path.c_str());
    }

    try
    {
        const auto json = json_value::parse(file);

        const auto& runtime_target = json.at(_X("runtimeTarget"));

        const pal::string_t& name = runtime_target.is_string()?
            runtime_target.as_string():
            runtime_target.at(_X("name")).as_string();

        trace::verbose(_X("Loading deps file... %s as portable=[%d]"), deps_path.c_str(), portable);

        return (portable) ? load_portable(json, name, rid_fallback_graph) : load_standalone(json, name);
    }
    catch (const std::exception& je)
    {
        pal::string_t jes;
        (void) pal::utf8_palstring(je.what(), &jes);
        trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), deps_path.c_str(), jes.c_str());
        return false;
    }
}
Пример #13
0
bool pal::file_exists(const pal::string_t& path)
{
    if (path.empty())
    {
        return false;
    }
    struct stat buffer;
    return (::stat(path.c_str(), &buffer) == 0);
}
Пример #14
0
pal::string_t resolve_sdk_version(pal::string_t sdk_path)
{
    trace::verbose(_X("--- Resolving SDK version from SDK dir [%s]"), sdk_path.c_str());

    pal::string_t retval;
    std::vector<pal::string_t> versions;

    pal::readdir(sdk_path, &versions);
    fx_ver_t max_ver(-1, -1, -1);
    fx_ver_t max_pre(-1, -1, -1);
    for (const auto& version : versions)
    {
        trace::verbose(_X("Considering version... [%s]"), version.c_str());

        fx_ver_t ver(-1, -1, -1);
        if (fx_ver_t::parse(version, &ver, true))
        {
            max_ver = std::max(ver, max_ver);
        }
        if (fx_ver_t::parse(version, &ver, false))
        {
            max_pre = std::max(ver, max_pre);
        }
    }

    // No production, use the max pre-release.
    if (max_ver == fx_ver_t(-1, -1, -1))
    {
        trace::verbose(_X("No production version found, so using latest prerelease"));
        max_ver = max_pre;
    }

    pal::string_t max_ver_str = max_ver.as_str();
    append_path(&sdk_path, max_ver_str.c_str());

    trace::verbose(_X("Checking if resolved SDK dir [%s] exists"), sdk_path.c_str());
    if (pal::directory_exists(sdk_path))
    {
        retval = sdk_path;
    }

    trace::verbose(_X("Resolved SDK dir is [%s]"), retval.c_str());
    return retval;
}
Пример #15
0
void tpafile::add_from_local_dir(const pal::string_t& dir)
{
	trace::verbose(_X("adding files from %s to TPA"), dir.c_str());
	const pal::char_t * const tpa_extensions[] = {
		_X(".ni.dll"),      // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
		_X(".dll"),
		_X(".ni.exe"),
		_X(".exe"),
	};

	std::set<pal::string_t> added_assemblies;

	// Get directory entries
	auto files = pal::readdir(dir);
	for (auto ext : tpa_extensions)
	{
		auto len = pal::strlen(ext);
		for (auto file : files)
		{
			// Can't be a match if it's the same length as the extension :)
			if (file.length() > len)
			{
				// Extract the same amount of text from the end of file name
				auto file_ext = file.substr(file.length() - len, len);

				// Check if this file name matches
				if (pal::strcasecmp(ext, file_ext.c_str()) == 0)
				{
					// Get the assembly name by stripping the extension
					// and add it to the set so we can de-dupe
					auto asm_name = file.substr(0, file.length() - len);

					// TODO(anurse): Also check if already in TPA file
					if (added_assemblies.find(asm_name) == added_assemblies.end())
					{
						added_assemblies.insert(asm_name);

						tpaentry_t entry;
						entry.asset_type = pal::string_t(_X("runtime"));
						entry.library_name = pal::string_t(asm_name);
						entry.library_version = pal::string_t(_X(""));

						pal::string_t relpath(dir);
						relpath.push_back(DIR_SEPARATOR);
						relpath.append(file);
						entry.relative_path = relpath;
						entry.asset_name = asm_name;

						trace::verbose(_X("adding %s to TPA list from %s"), asm_name.c_str(), relpath.c_str());
						m_entries.push_back(entry);
					}
				}
			}
		}
	}
}
Пример #16
0
/**
* When the framework is referenced more than once in a non-compatible way, display detailed error message
*   about available frameworks and installation of new framework.
*/
void fx_resolver_t::display_incompatible_framework_error(
    const pal::string_t& higher,
    const fx_reference_t& lower)
{
    trace::error(_X("The specified framework '%s', version '%s', apply_patches=%d, roll_forward=%s cannot roll-forward to the previously referenced version '%s'."),
        lower.get_fx_name().c_str(),
        lower.get_fx_version().c_str(),
        lower.get_apply_patches(),
        roll_forward_option_to_string(lower.get_roll_forward()).c_str(),
        higher.c_str());
}
Пример #17
0
static
bool is_executable(const pal::string_t& file_path)
{
    struct stat st;
    if (::stat(file_path.c_str(), &st) < 0)
    {
        return false;
    }

    return ((st.st_mode & S_IEXEC) != 0);
}
Пример #18
0
/*static*/ bool framework_info::print_all_frameworks(const pal::string_t& own_dir, const pal::string_t& leading_whitespace)
{
    std::vector<framework_info> framework_infos;
    get_all_framework_infos(own_dir, _X(""), &framework_infos);
    for (framework_info info : framework_infos)
    {
        trace::println(_X("%s%s %s [%s]"), leading_whitespace.c_str(), info.name.c_str(), info.version.as_str().c_str(), info.path.c_str());
    }

    return framework_infos.size() > 0;
}
Пример #19
0
bool pal::touch_file(const pal::string_t& path)
{
    HANDLE hnd = ::CreateFileW(path.c_str(), 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hnd == INVALID_HANDLE_VALUE)
    {
        trace::verbose(_X("Failed to leave breadcrumb, HRESULT: 0x%X"), HRESULT_FROM_WIN32(GetLastError()));
        return false;
    }
    ::CloseHandle(hnd);
    return true;
}
Пример #20
0
bool get_env_shared_store_dirs(std::vector<pal::string_t>* dirs, const pal::string_t& arch, const pal::string_t& tfm)
{
    pal::string_t path;
    if (!pal::getenv(_X("DOTNET_SHARED_STORE"), &path))
    {
        return false;
    }

    pal::string_t tok;
    pal::stringstream_t ss(path);
    while (std::getline(ss, tok, PATH_SEPARATOR))
    {
        if (pal::realpath(&tok))
        {
            append_path(&tok, arch.c_str());
            append_path(&tok, tfm.c_str());
            dirs->push_back(tok);
        }
    }
    return true;
}
Пример #21
0
pal::string_t fx_muxer_t::resolve_fx_dir(const pal::string_t& muxer_dir, runtime_config_t* runtime)
{
    trace::verbose(_X("--- Resolving FX directory from muxer dir [%s]"), muxer_dir.c_str());
    const auto fx_name = runtime->get_fx_name();
    const auto fx_ver = runtime->get_fx_version();
    const auto roll_fwd = runtime->get_fx_roll_fwd();

    fx_ver_t specified(-1, -1, -1);
    if (!fx_ver_t::parse(fx_ver, &specified, false))
    {
        trace::error(_X("The specified runtimeconfig.json version [%s] could not be parsed"), fx_ver.c_str());
        return pal::string_t();
    }

    auto fx_dir = muxer_dir;
    append_path(&fx_dir, _X("shared"));
    append_path(&fx_dir, fx_name.c_str());

    // If not roll forward or if pre-release, just return.
    if (!roll_fwd || specified.is_prerelease())
    {
        trace::verbose(_X("Did not roll forward because rollfwd=%d and [%s] is prerelease=%d"),
                roll_fwd, fx_ver.c_str(), specified.is_prerelease());
        append_path(&fx_dir, fx_ver.c_str());
    }
    else
    {
        trace::verbose(_X("Attempting production FX roll forward starting from [%s]"), fx_ver.c_str());

        std::vector<pal::string_t> list;
        pal::readdir(fx_dir, &list);
        fx_ver_t max_specified = specified;
        for (const auto& version : list)
        {
            trace::verbose(_X("Inspecting version... [%s]"), version.c_str());
            fx_ver_t ver(-1, -1, -1);
            if (fx_ver_t::parse(version, &ver, true) &&
                ver.get_major() == max_specified.get_major() &&
                ver.get_minor() == max_specified.get_minor())
            {
                max_specified.set_patch(std::max(ver.get_patch(), max_specified.get_patch()));
            }
        }
        pal::string_t max_specified_str = max_specified.as_str();
        append_path(&fx_dir, max_specified_str.c_str());
    }

    trace::verbose(_X("Chose FX version [%s]"), fx_dir.c_str());
    return fx_dir;
}
Пример #22
0
void fx_resolver_t::display_compatible_framework_trace(
    const pal::string_t& higher,
    const fx_reference_t& lower)
{
    if (trace::is_enabled())
    {
        trace::verbose(_X("--- The specified framework '%s', version '%s', apply_patches=%d, roll_forward=%s is compatible with the previously referenced version '%s'."),
            lower.get_fx_name().c_str(),
            lower.get_fx_version().c_str(),
            lower.get_apply_patches(),
            roll_forward_option_to_string(lower.get_roll_forward()).c_str(),
            higher.c_str());
    }
}
Пример #23
0
pal::string_t fx_muxer_t::resolve_cli_version(const pal::string_t& global_json)
{
    trace::verbose(_X("--- Resolving CLI version from global json [%s]"), global_json.c_str());

    pal::string_t retval;
    if (!pal::file_exists(global_json))
    {
        trace::verbose(_X("[%s] does not exist"), global_json.c_str());
        return retval;
    }

    pal::ifstream_t file(global_json);
    if (!file.good())
    {
        trace::verbose(_X("[%s] could not be opened"), global_json.c_str());
        return retval;
    }

    if (skip_utf8_bom(&file))
    {
        trace::verbose(_X("UTF-8 BOM skipped while reading [%s]"), global_json.c_str());
    }

    try
    {
        const auto root = json_value::parse(file);
        const auto& json = root.as_object();
        const auto sdk_iter = json.find(_X("sdk"));
        if (sdk_iter == json.end() || sdk_iter->second.is_null())
        {
            trace::verbose(_X("CLI '/sdk/version' field not present/null in [%s]"), global_json.c_str());
            return retval;
        }

        const auto& sdk_obj = sdk_iter->second.as_object();
        const auto ver_iter = sdk_obj.find(_X("version"));
        if (ver_iter == sdk_obj.end() || ver_iter->second.is_null())
        {
            trace::verbose(_X("CLI 'sdk/version' field not present/null in [%s]"), global_json.c_str());
            return retval;
        }
        retval = ver_iter->second.as_string();
    }
    catch (const std::exception& je)
    {
        pal::string_t jes;
        (void) pal::utf8_palstring(je.what(), &jes);
        trace::error(_X("A JSON parsing exception occurred in [%s]: %s"), global_json.c_str(), jes.c_str());
    }
    trace::verbose(_X("CLI version is [%s] in global json file [%s]"), retval.c_str(), global_json.c_str());
    return retval;
}
Пример #24
0
/**
* When the framework is not found, display detailed error message
*   about available frameworks and installation of new framework.
*/
void fx_resolver_t::display_missing_framework_error(
    const pal::string_t& fx_name,
    const pal::string_t& fx_version,
    const pal::string_t& fx_dir,
    const pal::string_t& dotnet_root)
{
    std::vector<framework_info> framework_infos;
    pal::string_t fx_ver_dirs;
    if (fx_dir.length())
    {
        fx_ver_dirs = fx_dir;
        framework_info::get_all_framework_infos(get_directory(fx_dir), fx_name, &framework_infos);
    }
    else
    {
        fx_ver_dirs = dotnet_root;
    }

    framework_info::get_all_framework_infos(dotnet_root, fx_name, &framework_infos);

    // Display the error message about missing FX.
    if (fx_version.length())
    {
        trace::error(_X("The specified framework '%s', version '%s' was not found."), fx_name.c_str(), fx_version.c_str());
    }
    else
    {
        trace::error(_X("The specified framework '%s' was not found."), fx_name.c_str());
    }

    if (framework_infos.size())
    {
        trace::error(_X("  - The following frameworks were found:"));
        for (const framework_info& info : framework_infos)
        {
            trace::error(_X("      %s at [%s]"), info.version.as_str().c_str(), info.path.c_str());
        }
    }
    else
    {
        trace::error(_X("  - No frameworks were found."));
    }

    trace::error(_X(""));
    trace::error(_X("You can resolve the problem by installing the specified framework and/or SDK."));
    trace::error(_X(""));
    trace::error(_X("The .NET Core frameworks can be found at:"));
    trace::error(_X("  - %s"), DOTNET_CORE_DOWNLOAD_URL);
}
Пример #25
0
void pal::readdir(const pal::string_t& path, std::vector<pal::string_t>* list)
{
    assert(list != nullptr);

    std::vector<pal::string_t>& files = *list;

    auto dir = opendir(path.c_str());
    if (dir != nullptr)
    {
        struct dirent* entry = nullptr;
        while((entry = readdir(dir)) != nullptr)
        {
            // We are interested in files only
            switch (entry->d_type)
            {
            case DT_REG:
                break;

            // Handle symlinks and file systems that do not support d_type
            case DT_LNK:
            case DT_UNKNOWN:
                {
                    std::string fullFilename;

                    fullFilename.append(path);
                    fullFilename.push_back(DIR_SEPARATOR);
                    fullFilename.append(entry->d_name);

                    struct stat sb;
                    if (stat(fullFilename.c_str(), &sb) == -1)
                    {
                        continue;
                    }

                    if (!S_ISREG(sb.st_mode))
                    {
                        continue;
                    }
                }
                break;

            default:
                continue;
            }

            files.push_back(pal::string_t(entry->d_name));
        }
    }
}
Пример #26
0
bool library_exists_in_dir(const pal::string_t& lib_dir, const pal::string_t& lib_name, pal::string_t* p_lib_path)
{
    pal::string_t lib_path = lib_dir;
    append_path(&lib_path, lib_name.c_str());

    if (!pal::file_exists(lib_path))
    {
        return false;
    }
    if (p_lib_path)
    {
        *p_lib_path = lib_path;
    }
    return true;
}
Пример #27
0
static void readdir(const pal::string_t& path, const pal::string_t& pattern, bool onlydirectories, std::vector<pal::string_t>* list)
{
    assert(list != nullptr);

    std::vector<pal::string_t>& files = *list;
    pal::string_t normalized_path(path);

    if (LongFile::ShouldNormalize(normalized_path))
    {
        if (!pal::realpath(&normalized_path))
        {
            return;
        }
    }

    pal::string_t search_string(normalized_path);
    append_path(&search_string, pattern.c_str());

    WIN32_FIND_DATAW data = { 0 };

    auto handle = ::FindFirstFileExW(search_string.c_str(), FindExInfoStandard, &data, FindExSearchNameMatch, NULL, 0);
    if (handle == INVALID_HANDLE_VALUE)
    {
        return;
    }
    do
    {
        if (!onlydirectories || (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        {
            pal::string_t filepath(data.cFileName);
            if (filepath != _X(".") && filepath != _X(".."))
            {
                files.push_back(filepath);
            }
        }
    } while (::FindNextFileW(handle, &data));
    ::FindClose(handle);
}
Пример #28
0
bool report_missing_assembly_in_manifest(const deps_entry_t& entry, bool continueResolving = false)
{
    bool showManifestListMessage = !entry.runtime_store_manifest_list.empty();

    if (entry.asset_type == deps_entry_t::asset_types::resources)
    {
        // Treat missing resource assemblies as informational.
        continueResolving = true;

        trace::info(MissingAssemblyMessage.c_str(), _X("Info"),
            entry.deps_file.c_str(), entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str());

        if (showManifestListMessage)
        {
            trace::info(ManifestListMessage.c_str(), entry.runtime_store_manifest_list.c_str());
        }
    }
    else if (continueResolving)
    {
        trace::warning(MissingAssemblyMessage.c_str(), _X("Warning"),
            entry.deps_file.c_str(), entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str());

        if (showManifestListMessage)
        {
            trace::warning(ManifestListMessage.c_str(), entry.runtime_store_manifest_list.c_str());
        }
    }
    else
    {
        trace::error(MissingAssemblyMessage.c_str(), _X("Error"),
            entry.deps_file.c_str(), entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str());

        if (showManifestListMessage)
        {
            trace::error(ManifestListMessage.c_str(), entry.runtime_store_manifest_list.c_str());
        }
    }

    return continueResolving;
}
Пример #29
0
bool deps_resolver_t::try_roll_forward(const deps_entry_t& entry,
    const pal::string_t& probe_dir,
    bool patch_roll_fwd,
    bool prerelease_roll_fwd,
    pal::string_t* candidate)
{
    trace::verbose(_X("Attempting a roll forward for [%s/%s/%s] in [%s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.relative_path.c_str(), probe_dir.c_str());

    const pal::string_t& lib_ver = entry.library_version;

    fx_ver_t cur_ver(-1, -1, -1);
    if (!fx_ver_t::parse(lib_ver, &cur_ver, false))
    {
        trace::verbose(_X("No roll forward as specified version [%s] could not be parsed"), lib_ver.c_str());
        return false;
    }
    pal::string_t path = probe_dir;
    append_path(&path, entry.library_name.c_str());
    pal::string_t max_str = lib_ver;
    if (cur_ver.is_prerelease() && prerelease_roll_fwd)
    {
        pal::string_t maj_min_pat_star = cur_ver.prerelease_glob();

        pal::string_t cache_key = path;
        append_path(&cache_key, maj_min_pat_star.c_str());

        if (m_prerelease_roll_forward_cache.count(cache_key))
        {
            max_str = m_prerelease_roll_forward_cache[cache_key];
            trace::verbose(_X("Found cached roll forward version [%s] -> [%s]"), lib_ver.c_str(), max_str.c_str());
        }
        else
        {
            try_prerelease_roll_forward_in_dir(path, cur_ver, &max_str);
            m_prerelease_roll_forward_cache[cache_key] = max_str;
        }
    }
    if (!cur_ver.is_prerelease() && patch_roll_fwd)
    {
        // Extract glob string of the form: 1.0.* from the version 1.0.0-prerelease-00001.
        pal::string_t maj_min_star = cur_ver.patch_glob();

        pal::string_t cache_key = path;
        append_path(&cache_key, maj_min_star.c_str());

        if (m_patch_roll_forward_cache.count(cache_key))
        {
            max_str = m_patch_roll_forward_cache[cache_key];
            trace::verbose(_X("Found cached roll forward version [%s] -> [%s]"), lib_ver.c_str(), max_str.c_str());
        }
        else
        {
            try_patch_roll_forward_in_dir(path, cur_ver, &max_str);
            m_patch_roll_forward_cache[cache_key] = max_str;
        }
    }
    append_path(&path, max_str.c_str());

    return entry.to_rel_path(path, candidate);
}
Пример #30
0
int execute_app(
    const pal::string_t& impl_dll_dir,
    corehost_init_t* init,
    const int argc,
    const pal::char_t* argv[])
{
    pal::dll_t corehost;
    corehost_main_fn host_main = nullptr;
    corehost_load_fn host_load = nullptr;
    corehost_unload_fn host_unload = nullptr;

    int code = load_host_library(impl_dll_dir, &corehost, &host_load, &host_main, &host_unload);
    if (code != StatusCode::Success)
    {
        trace::error(_X("An error occurred while loading required library %s from [%s]"), LIBHOSTPOLICY_NAME, impl_dll_dir.c_str());
        return code;
    }

    // Previous hostfxr trace messages must be printed before calling trace::setup in hostpolicy
    trace::flush();

    const host_interface_t& intf = init->get_host_init_data();
    if ((code = host_load(&intf)) == 0)
    {
        code = host_main(argc, argv);
        (void)host_unload();
    }

    pal::unload_library(corehost);

    return code;
}