-/*
- * assembly.c: Routines for loading assemblies.
+/**
+ * \file
+ * Routines for loading assemblies.
*
* Author:
* Miguel de Icaza (miguel@ximian.com)
guint8 version_set_index;
const char* new_assembly_name;
gboolean only_lower_versions;
+ gboolean framework_facade_assembly;
} AssemblyVersionMap;
+/* Flag bits for assembly_names_equal_flags (). */
+typedef enum {
+ /* Default comparison: all fields must match */
+ ANAME_EQ_NONE = 0x0,
+ /* Don't compare public key token */
+ ANAME_EQ_IGNORE_PUBKEY = 0x1,
+ /* Don't compare the versions */
+ ANAME_EQ_IGNORE_VERSION = 0x2,
+
+ ANAME_EQ_MASK = 0x3
+} AssemblyNameEqFlags;
+
/* the default search path is empty, the first slot is replaced with the computed value */
static const char*
default_path [] = {
static char **extra_gac_paths = NULL;
#ifndef DISABLE_ASSEMBLY_REMAPPING
+
+#define FACADE_ASSEMBLY(str) {str, 0, NULL, FALSE, TRUE}
+
+static GHashTable* assembly_remapping_table;
/* The list of system assemblies what will be remapped to the running
- * runtime version. WARNING: this list must be sorted.
+ * runtime version.
+ * This list is stored in @assembly_remapping_table during initialization.
+ * Keep it sorted just to make maintenance easier.
+ *
* The integer number is an index in the MonoRuntimeInfo structure, whose
* values can be found in domain.c - supported_runtimes. Look there
* to understand what remapping will be made.
{"Novell.Directory.Ldap", 0},
{"PEAPI", 0},
{"System", 0},
+ FACADE_ASSEMBLY ("System.AppContext"),
+ FACADE_ASSEMBLY ("System.Collections"),
+ FACADE_ASSEMBLY ("System.Collections.Concurrent"),
+ FACADE_ASSEMBLY ("System.Collections.NonGeneric"),
+ FACADE_ASSEMBLY ("System.Collections.Specialized"),
+ FACADE_ASSEMBLY ("System.ComponentModel"),
+ FACADE_ASSEMBLY ("System.ComponentModel.Annotations"),
{"System.ComponentModel.Composition", 2},
{"System.ComponentModel.DataAnnotations", 2},
+ FACADE_ASSEMBLY ("System.ComponentModel.EventBasedAsync"),
+ FACADE_ASSEMBLY ("System.ComponentModel.Primitives"),
+ FACADE_ASSEMBLY ("System.ComponentModel.TypeConverter"),
{"System.Configuration", 0},
{"System.Configuration.Install", 0},
+ FACADE_ASSEMBLY ("System.Console"),
{"System.Core", 2},
{"System.Data", 0},
+ FACADE_ASSEMBLY ("System.Data.Common"),
{"System.Data.Linq", 2},
{"System.Data.OracleClient", 0},
{"System.Data.Services", 2},
{"System.Data.Services.Client", 2},
+ FACADE_ASSEMBLY ("System.Data.SqlClient"),
{"System.Data.SqlXml", 0},
{"System.Design", 0},
+ FACADE_ASSEMBLY ("System.Diagnostics.Contracts"),
+ FACADE_ASSEMBLY ("System.Diagnostics.Debug"),
+ FACADE_ASSEMBLY ("System.Diagnostics.FileVersionInfo"),
+ FACADE_ASSEMBLY ("System.Diagnostics.Process"),
+ FACADE_ASSEMBLY ("System.Diagnostics.StackTrace"),
+ FACADE_ASSEMBLY ("System.Diagnostics.TextWriterTraceListener"),
+ FACADE_ASSEMBLY ("System.Diagnostics.Tools"),
+ FACADE_ASSEMBLY ("System.Diagnostics.TraceEvent"),
+ FACADE_ASSEMBLY ("System.Diagnostics.TraceSource"),
+ FACADE_ASSEMBLY ("System.Diagnostics.Tracing"),
{"System.DirectoryServices", 0},
{"System.Drawing", 0},
{"System.Drawing.Design", 0},
+ FACADE_ASSEMBLY ("System.Drawing.Primitives"),
+ FACADE_ASSEMBLY ("System.Dynamic.Runtime"),
{"System.EnterpriseServices", 0},
+ FACADE_ASSEMBLY ("System.Globalization"),
+ FACADE_ASSEMBLY ("System.Globalization.Calendars"),
+ FACADE_ASSEMBLY ("System.Globalization.Extensions"),
{"System.IdentityModel", 3},
{"System.IdentityModel.Selectors", 3},
+ FACADE_ASSEMBLY ("System.IO"),
{"System.IO.Compression", 2},
+ FACADE_ASSEMBLY ("System.IO.Compression.ZipFile"),
+ FACADE_ASSEMBLY ("System.IO.FileSystem"),
+ FACADE_ASSEMBLY ("System.IO.FileSystem.AccessControl"),
+ FACADE_ASSEMBLY ("System.IO.FileSystem.DriveInfo"),
+ FACADE_ASSEMBLY ("System.IO.FileSystem.Primitives"),
+ FACADE_ASSEMBLY ("System.IO.FileSystem.Watcher"),
+ FACADE_ASSEMBLY ("System.IO.IsolatedStorage"),
+ FACADE_ASSEMBLY ("System.IO.MemoryMappedFiles"),
+ FACADE_ASSEMBLY ("System.IO.Packaging"),
+ FACADE_ASSEMBLY ("System.IO.Pipes"),
+ FACADE_ASSEMBLY ("System.IO.UnmanagedMemoryStream"),
+ FACADE_ASSEMBLY ("System.Linq"),
+ FACADE_ASSEMBLY ("System.Linq.Expressions"),
+ FACADE_ASSEMBLY ("System.Linq.Parallel"),
+ FACADE_ASSEMBLY ("System.Linq.Queryable"),
{"System.Management", 0},
{"System.Messaging", 0},
{"System.Net", 2},
- {"System.Net.Http", 3},
+ FACADE_ASSEMBLY ("System.Net.AuthenticationManager"),
+ FACADE_ASSEMBLY ("System.Net.Cache"),
+ {"System.Net.Http", 4},
+ {"System.Net.Http.Rtc", 0},
+ FACADE_ASSEMBLY ("System.Net.HttpListener"),
+ {"System.Net.NetworkInformation", 0},
+ FACADE_ASSEMBLY ("System.Net.Mail"),
+ FACADE_ASSEMBLY ("System.Net.NameResolution"),
+ FACADE_ASSEMBLY ("System.Net.NetworkInformation"),
+ FACADE_ASSEMBLY ("System.Net.Ping"),
+ FACADE_ASSEMBLY ("System.Net.Primitives"),
+ FACADE_ASSEMBLY ("System.Net.Requests"),
+ FACADE_ASSEMBLY ("System.Net.Security"),
+ FACADE_ASSEMBLY ("System.Net.ServicePoint"),
+ FACADE_ASSEMBLY ("System.Net.Sockets"),
+ FACADE_ASSEMBLY ("System.Net.Utilities"),
+ FACADE_ASSEMBLY ("System.Net.WebHeaderCollection"),
+ FACADE_ASSEMBLY ("System.Net.WebSockets"),
+ FACADE_ASSEMBLY ("System.Net.WebSockets.Client"),
{"System.Numerics.Vectors", 3},
+ FACADE_ASSEMBLY ("System.ObjectModel"),
+ FACADE_ASSEMBLY ("System.Reflection"),
+ FACADE_ASSEMBLY ("System.Reflection.Emit"),
+ FACADE_ASSEMBLY ("System.Reflection.Emit.ILGeneration"),
+ FACADE_ASSEMBLY ("System.Reflection.Emit.Lightweight"),
+ FACADE_ASSEMBLY ("System.Reflection.Extensions"),
+ FACADE_ASSEMBLY ("System.Reflection.Primitives"),
+ FACADE_ASSEMBLY ("System.Reflection.TypeExtensions"),
+ FACADE_ASSEMBLY ("System.Resources.ReaderWriter"),
+ FACADE_ASSEMBLY ("System.Resources.ResourceManager"),
+ FACADE_ASSEMBLY ("System.Runtime"),
+ FACADE_ASSEMBLY ("System.Runtime.CompilerServices.VisualC"),
+ FACADE_ASSEMBLY ("System.Runtime.Extensions"),
+ FACADE_ASSEMBLY ("System.Runtime.Handles"),
+ FACADE_ASSEMBLY ("System.Runtime.InteropServices"),
{"System.Runtime.InteropServices.RuntimeInformation", 2},
+ FACADE_ASSEMBLY ("System.Runtime.InteropServices.WindowsRuntime"),
+ FACADE_ASSEMBLY ("System.Runtime.Numerics"),
{"System.Runtime.Remoting", 0},
{"System.Runtime.Serialization", 3},
{"System.Runtime.Serialization.Formatters", 3},
{"System.Runtime.Serialization.Formatters.Soap", 0},
+ FACADE_ASSEMBLY ("System.Runtime.Serialization.Json"),
+ FACADE_ASSEMBLY ("System.Runtime.Serialization.Primitives"),
+ FACADE_ASSEMBLY ("System.Runtime.Serialization.Xml"),
{"System.Security", 0},
+ FACADE_ASSEMBLY ("System.Security.AccessControl"),
+ FACADE_ASSEMBLY ("System.Security.Claims"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Algorithms"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Cng"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Csp"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.DeriveBytes"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Encoding"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.Aes"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.ECDiffieHellman"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.ECDsa"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.Hashing"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.Hashing.Algorithms"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.OpenSsl"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Pkcs"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.Primitives"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.ProtectedData"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.RSA"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.RandomNumberGenerator"),
+ FACADE_ASSEMBLY ("System.Security.Cryptography.X509Certificates"),
+ FACADE_ASSEMBLY ("System.Security.Principal"),
+ FACADE_ASSEMBLY ("System.Security.Principal.Windows"),
+ FACADE_ASSEMBLY ("System.Security.SecureString"),
{"System.ServiceModel", 3},
{"System.ServiceModel.Duplex", 3},
{"System.ServiceModel.Http", 3},
{"System.ServiceModel.Security", 3},
{"System.ServiceModel.Web", 2},
{"System.ServiceProcess", 0},
- {"System.Text.Encoding.CodePages", 3},
+ FACADE_ASSEMBLY ("System.ServiceProcess.ServiceController"),
+ FACADE_ASSEMBLY ("System.Text.Encoding"),
+ FACADE_ASSEMBLY ("System.Text.Encoding.CodePages"),
+ FACADE_ASSEMBLY ("System.Text.Encoding.Extensions"),
+ FACADE_ASSEMBLY ("System.Text.RegularExpressions"),
+ FACADE_ASSEMBLY ("System.Threading"),
+ FACADE_ASSEMBLY ("System.Threading.AccessControl"),
+ FACADE_ASSEMBLY ("System.Threading.Overlapped"),
+ FACADE_ASSEMBLY ("System.Threading.Tasks"),
+ FACADE_ASSEMBLY ("System.Threading.Tasks.Parallel"),
+ FACADE_ASSEMBLY ("System.Threading.Thread"),
+ FACADE_ASSEMBLY ("System.Threading.ThreadPool"),
+ FACADE_ASSEMBLY ("System.Threading.Timer"),
{"System.Transactions", 0},
+ FACADE_ASSEMBLY ("System.ValueTuple"),
{"System.Web", 0},
{"System.Web.Abstractions", 2},
{"System.Web.DynamicData", 2},
{"System.Web.Mobile", 0},
{"System.Web.Routing", 2},
{"System.Web.Services", 0},
+ {"System.Windows", 0},
{"System.Windows.Forms", 0},
{"System.Xml", 0},
{"System.Xml.Linq", 2},
- {"System.Xml.ReaderWriter", 3},
+ FACADE_ASSEMBLY ("System.Xml.ReaderWriter"),
+ {"System.Xml.Serialization", 0},
+ FACADE_ASSEMBLY ("System.Xml.XDocument"),
+ FACADE_ASSEMBLY ("System.Xml.XPath"),
{"System.Xml.XPath.XmlDocument", 3},
+ FACADE_ASSEMBLY ("System.Xml.XPath.XDocument"),
+ FACADE_ASSEMBLY ("System.Xml.XmlDocument"),
+ FACADE_ASSEMBLY ("System.Xml.XmlSerializer"),
+ FACADE_ASSEMBLY ("System.Xml.Xsl.Primitives"),
{"WindowsBase", 3},
- {"mscorlib", 0}
+ {"mscorlib", 0},
+ FACADE_ASSEMBLY ("netstandard"),
};
#endif
static MonoAssembly*
prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refonly);
+static gboolean
+assembly_names_equal_flags (MonoAssemblyName *l, MonoAssemblyName *r, AssemblyNameEqFlags flags);
+
+/* Assembly name matching */
+static gboolean
+exact_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *candidate_name);
+static gboolean
+framework_assembly_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *candidate_name);
+
static gchar*
encode_public_tok (const guchar *token, gint32 len)
{
/**
* mono_public_tokens_are_equal:
- * @pubt1: first public key token
- * @pubt2: second public key token
+ * \param pubt1 first public key token
+ * \param pubt2 second public key token
*
- * Compare two public key tokens and return #TRUE is they are equal and #FALSE
+ * Compare two public key tokens and return TRUE is they are equal and FALSE
* otherwise.
*/
gboolean
/**
* mono_set_assemblies_path:
- * @path: list of paths that contain directories where Mono will look for assemblies
+ * \param path list of paths that contain directories where Mono will look for assemblies
*
* Use this method to override the standard assembly lookup system and
* override any assemblies coming from the GAC. This is the method
- * that supports the MONO_PATH variable.
+ * that supports the \c MONO_PATH variable.
*
- * Notice that MONO_PATH and this method are really a very bad idea as
+ * Notice that \c MONO_PATH and this method are really a very bad idea as
* it prevents the GAC from working and it prevents the standard
* resolution mechanisms from working. Nonetheless, for some debugging
* situations and bootstrapping setups, this is useful to have.
}
*dest = *splitted;
- if (g_getenv ("MONO_DEBUG") == NULL)
+ if (g_hasenv ("MONO_DEBUG"))
return;
splitted = assemblies_path;
static void
check_path_env (void)
{
- const char* path;
- path = g_getenv ("MONO_PATH");
+ if (assemblies_path != NULL)
+ return;
+
+ char* path = g_getenv ("MONO_PATH");
#ifdef __native_client__
if (!path)
- path = nacl_mono_path;
+ path = strdup (nacl_mono_path);
#endif
- if (!path || assemblies_path != NULL)
+ if (!path)
return;
mono_set_assemblies_path(path);
+ g_free (path);
}
static void
-check_extra_gac_path_env (void) {
- const char *path;
+check_extra_gac_path_env (void)
+{
+ char *path;
char **splitted, **dest;
path = g_getenv ("MONO_GAC_PREFIX");
return;
splitted = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 1000);
+ g_free (path);
+
if (extra_gac_paths)
g_strfreev (extra_gac_paths);
extra_gac_paths = dest = splitted;
}
*dest = *splitted;
- if (g_getenv ("MONO_DEBUG") == NULL)
+ if (!g_hasenv ("MONO_DEBUG"))
return;
while (*splitted) {
/**
* mono_assembly_names_equal:
- * @l: first assembly
- * @r: second assembly.
+ * \param l first assembly
+ * \param r second assembly.
*
- * Compares two MonoAssemblyNames and returns whether they are equal.
+ * Compares two \c MonoAssemblyName instances and returns whether they are equal.
*
* This compares the names, the cultures, the release version and their
* public tokens.
*
- * Returns: TRUE if both assembly names are equal.
+ * \returns TRUE if both assembly names are equal.
*/
gboolean
mono_assembly_names_equal (MonoAssemblyName *l, MonoAssemblyName *r)
+{
+ return assembly_names_equal_flags (l, r, ANAME_EQ_NONE);
+}
+
+gboolean
+assembly_names_equal_flags (MonoAssemblyName *l, MonoAssemblyName *r, AssemblyNameEqFlags flags)
{
if (!l->name || !r->name)
return FALSE;
if (l->culture && r->culture && strcmp (l->culture, r->culture))
return FALSE;
- if (l->major != r->major || l->minor != r->minor ||
- l->build != r->build || l->revision != r->revision)
+ if ((l->major != r->major || l->minor != r->minor ||
+ l->build != r->build || l->revision != r->revision) &&
+ (flags & ANAME_EQ_IGNORE_VERSION) == 0)
if (! ((l->major == 0 && l->minor == 0 && l->build == 0 && l->revision == 0) || (r->major == 0 && r->minor == 0 && r->build == 0 && r->revision == 0)))
return FALSE;
- if (!l->public_key_token [0] || !r->public_key_token [0])
+ if (!l->public_key_token [0] || !r->public_key_token [0] || (flags & ANAME_EQ_IGNORE_PUBKEY) != 0)
return TRUE;
if (!mono_public_tokens_are_equal (l->public_key_token, r->public_key_token))
}
static MonoAssembly *
-load_in_path (const char *basename, const char** search_path, MonoImageOpenStatus *status, MonoBoolean refonly)
+load_in_path (const char *basename, const char** search_path, MonoImageOpenStatus *status, MonoBoolean refonly, MonoAssemblyCandidatePredicate predicate, gpointer user_data)
{
int i;
char *fullpath;
for (i = 0; search_path [i]; ++i) {
fullpath = g_build_filename (search_path [i], basename, NULL);
- result = mono_assembly_open_full (fullpath, status, refonly);
+ result = mono_assembly_open_predicate (fullpath, refonly, FALSE, predicate, user_data, status);
g_free (fullpath);
if (result)
return result;
/**
* mono_assembly_setrootdir:
- * @root_dir: The pathname of the root directory where we will locate assemblies
+ * \param root_dir The pathname of the root directory where we will locate assemblies
*
* This routine sets the internal default root directory for looking up
* assemblies.
/**
* mono_set_dirs:
- * @assembly_dir: the base directory for assemblies
- * @config_dir: the base directory for configuration files
+ * \param assembly_dir the base directory for assemblies
+ * \param config_dir the base directory for configuration files
*
* This routine is used internally and by developers embedding
* the runtime into their own applications.
mono_os_mutex_init_recursive (&assemblies_mutex);
mono_os_mutex_init (&assembly_binding_mutex);
+
+#ifndef DISABLE_ASSEMBLY_REMAPPING
+ assembly_remapping_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ int i;
+ for (i = 0; i < G_N_ELEMENTS (framework_assemblies) - 1; ++i)
+ g_hash_table_insert (assembly_remapping_table, (void*)framework_assemblies [i].assembly_name, (void*)&framework_assemblies [i]);
+
+#endif
}
static void
return TRUE;
}
+/**
+ * mono_assembly_fill_assembly_name:
+ * \param image Image
+ * \param aname Name
+ * \returns TRUE if successful
+ */
gboolean
mono_assembly_fill_assembly_name (MonoImage *image, MonoAssemblyName *aname)
{
/**
* mono_stringify_assembly_name:
- * @aname: the assembly name.
+ * \param aname the assembly name.
*
- * Convert @aname into its string format. The returned string is dynamically
+ * Convert \p aname into its string format. The returned string is dynamically
* allocated and should be freed by the caller.
*
- * Returns: a newly allocated string with a string representation of
+ * \returns a newly allocated string with a string representation of
* the assembly name.
*/
char*
/**
* mono_assembly_addref:
- * @assemnly: the assembly to reference
+ * \param assembly the assembly to reference
*
* This routine increments the reference count on a MonoAssembly.
* The reference count is reduced every time the method mono_assembly_close() is
mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_aname)
{
const MonoRuntimeInfo *current_runtime;
- int pos, first, last;
if (aname->name == NULL) return aname;
}
#ifndef DISABLE_ASSEMBLY_REMAPPING
- first = 0;
- last = G_N_ELEMENTS (framework_assemblies) - 1;
-
- while (first <= last) {
- int res;
- pos = first + (last - first) / 2;
- res = strcmp (aname->name, framework_assemblies[pos].assembly_name);
- if (res == 0) {
- const AssemblyVersionSet* vset;
- int index = framework_assemblies[pos].version_set_index;
- g_assert (index < G_N_ELEMENTS (current_runtime->version_sets));
- vset = ¤t_runtime->version_sets [index];
-
- if (aname->major == vset->major && aname->minor == vset->minor &&
- aname->build == vset->build && aname->revision == vset->revision)
- return aname;
-
- if (framework_assemblies[pos].only_lower_versions && compare_versions ((AssemblyVersionSet*)vset, aname) < 0)
- return aname;
-
- if ((aname->major | aname->minor | aname->build | aname->revision) != 0)
- mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
- "The request to load the assembly %s v%d.%d.%d.%d was remapped to v%d.%d.%d.%d",
- aname->name,
- aname->major, aname->minor, aname->build, aname->revision,
- vset->major, vset->minor, vset->build, vset->revision
- );
-
- memcpy (dest_aname, aname, sizeof(MonoAssemblyName));
- dest_aname->major = vset->major;
- dest_aname->minor = vset->minor;
- dest_aname->build = vset->build;
- dest_aname->revision = vset->revision;
- if (framework_assemblies[pos].new_assembly_name != NULL) {
- dest_aname->name = framework_assemblies[pos].new_assembly_name;
- mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
- "The assembly name %s was remapped to %s",
- aname->name,
- dest_aname->name);
- }
- return dest_aname;
- } else if (res < 0) {
- last = pos - 1;
- } else {
- first = pos + 1;
+ const AssemblyVersionMap *vmap = (AssemblyVersionMap *)g_hash_table_lookup (assembly_remapping_table, aname->name);
+ if (vmap) {
+ const AssemblyVersionSet* vset;
+ int index = vmap->version_set_index;
+ g_assert (index < G_N_ELEMENTS (current_runtime->version_sets));
+ vset = ¤t_runtime->version_sets [index];
+
+ if (vmap->framework_facade_assembly) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Assembly %s is a framework Facade asseembly",
+ aname->name);
+ return aname;
}
+
+ if (aname->major == vset->major && aname->minor == vset->minor &&
+ aname->build == vset->build && aname->revision == vset->revision) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Found assembly remapping for %s and was for the same version %d.%d.%d.%d",
+ aname->name,
+ aname->major, aname->minor, aname->build, aname->revision);
+ return aname;
+ }
+
+ if (vmap->only_lower_versions && compare_versions ((AssemblyVersionSet*)vset, aname) < 0) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY,
+ "Found lower-versions-only assembly remaping to load %s %d.%d.%d.%d but mapping has %d.%d.%d.%d",
+ aname->name,
+ aname->major, aname->minor, aname->build, aname->revision,
+ vset->major, vset->minor, vset->build, vset->revision
+ );
+ return aname;
+ }
+
+ if ((aname->major | aname->minor | aname->build | aname->revision) != 0)
+ mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+ "The request to load the assembly %s v%d.%d.%d.%d was remapped to v%d.%d.%d.%d",
+ aname->name,
+ aname->major, aname->minor, aname->build, aname->revision,
+ vset->major, vset->minor, vset->build, vset->revision
+ );
+
+ memcpy (dest_aname, aname, sizeof(MonoAssemblyName));
+ dest_aname->major = vset->major;
+ dest_aname->minor = vset->minor;
+ dest_aname->build = vset->build;
+ dest_aname->revision = vset->revision;
+ if (vmap->new_assembly_name != NULL) {
+ dest_aname->name = vmap->new_assembly_name;
+ mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+ "The assembly name %s was remapped to %s",
+ aname->name,
+ dest_aname->name);
+ }
+ return dest_aname;
}
#endif
/**
* mono_assembly_get_assemblyref:
- * @image: pointer to the MonoImage to extract the information from.
- * @index: index to the assembly reference in the image.
- * @aname: pointer to a `MonoAssemblyName` that will hold the returned value.
+ * \param image pointer to the \c MonoImage to extract the information from.
+ * \param index index to the assembly reference in the image.
+ * \param aname pointer to a \c MonoAssemblyName that will hold the returned value.
*
- * Fills out the @aname with the assembly name of the @index assembly reference in @image.
+ * Fills out the \p aname with the assembly name of the \p index assembly reference in \p image.
*/
void
mono_assembly_get_assemblyref (MonoImage *image, int index, MonoAssemblyName *aname)
}
}
+/**
+ * mono_assembly_load_reference:
+ */
void
mono_assembly_load_reference (MonoImage *image, int index)
{
/**
* mono_assembly_load_references:
- * @image:
- * @status:
- * @deprecated: There is no reason to use this method anymore, it does nothing
+ * \param image
+ * \param status
+ * \deprecated There is no reason to use this method anymore, it does nothing
*
- * This method is now a no-op, it does nothing other than setting the @status to #MONO_IMAGE_OK
+ * This method is now a no-op, it does nothing other than setting the \p status to \c MONO_IMAGE_OK
*/
void
mono_assembly_load_references (MonoImage *image, MonoImageOpenStatus *status)
AssemblyLoadHook *assembly_load_hook = NULL;
+/**
+ * mono_assembly_invoke_load_hook:
+ */
void
mono_assembly_invoke_load_hook (MonoAssembly *ass)
{
}
}
+/**
+ * mono_install_assembly_load_hook:
+ */
void
mono_install_assembly_load_hook (MonoAssemblyLoadFunc func, gpointer user_data)
{
return NULL;
}
+/**
+ * mono_assembly_invoke_search_hook:
+ */
MonoAssembly*
mono_assembly_invoke_search_hook (MonoAssemblyName *aname)
{
assembly_search_hook = hook;
}
+/**
+ * mono_install_assembly_search_hook:
+ */
void
mono_install_assembly_search_hook (MonoAssemblySearchFunc func, gpointer user_data)
{
}
}
+/**
+ * mono_install_assembly_refonly_search_hook:
+ */
void
mono_install_assembly_refonly_search_hook (MonoAssemblySearchFunc func, gpointer user_data)
{
mono_install_assembly_search_hook_internal (func, user_data, TRUE, FALSE);
}
+/**
+ * mono_install_assembly_postload_search_hook:
+ */
void
mono_install_assembly_postload_search_hook (MonoAssemblySearchFunc func, gpointer user_data)
{
return NULL;
}
+/**
+ * mono_install_assembly_preload_hook:
+ */
void
mono_install_assembly_preload_hook (MonoAssemblyPreLoadFunc func, gpointer user_data)
{
assembly_preload_hook = hook;
}
+/**
+ * mono_install_assembly_refonly_preload_hook:
+ */
void
mono_install_assembly_refonly_preload_hook (MonoAssemblyPreLoadFunc func, gpointer user_data)
{
/**
* mono_assembly_open_from_bundle:
- * @filename: Filename requested
- * @status: return status code
+ * \param filename Filename requested
+ * \param status return status code
*
- * This routine tries to open the assembly specified by `filename' from the
+ * This routine tries to open the assembly specified by \p filename from the
* defined bundles, if found, returns the MonoImage for it, if not found
* returns NULL
*/
}
/**
- * mono_assemblies_open_full:
- * @filename: the file to load
- * @status: return status code
- * @refonly: Whether this assembly is being opened in "reflection-only" mode.
-*
- * This loads an assembly from the specified @filename. The @filename allows
- * a local URL (starting with a file:// prefix). If a file prefix is used, the
+ * mono_assembly_open_full:
+ * \param filename the file to load
+ * \param status return status code
+ * \param refonly Whether this assembly is being opened in "reflection-only" mode.
+ *
+ * This loads an assembly from the specified \p filename. The \p filename allows
+ * a local URL (starting with a \c file:// prefix). If a file prefix is used, the
* filename is interpreted as a URL, and the filename is URL-decoded. Otherwise the file
* is treated as a local path.
*
* First, an attempt is made to load the assembly from the bundled executable (for those
- * deployments that have been done with the `mkbundle` tool or for scenarios where the
+ * deployments that have been done with the \c mkbundle tool or for scenarios where the
* assembly has been registered as an embedded assembly). If this is not the case, then
* the assembly is loaded from disk using `api:mono_image_open_full`.
*
* If the pointed assembly does not live in the Global Assembly Cache, a shadow copy of
* the assembly is made.
*
- * If @refonly is set to true, then the assembly is loaded purely for inspection with
- * the `System.Reflection` API.
+ * If \p refonly is set to true, then the assembly is loaded purely for inspection with
+ * the \c System.Reflection API.
*
- * Returns: NULL on error, with the @status set to an error code, or a pointer
+ * \returns NULL on error, with the \p status set to an error code, or a pointer
* to the assembly.
*/
MonoAssembly *
mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboolean refonly)
+{
+ return mono_assembly_open_a_lot (filename, status, refonly, FALSE);
+}
+
+MonoAssembly *
+mono_assembly_open_a_lot (const char *filename, MonoImageOpenStatus *status, gboolean refonly, gboolean load_from_context)
+{
+ return mono_assembly_open_predicate (filename, refonly, load_from_context, NULL, NULL, status);
+}
+
+MonoAssembly *
+mono_assembly_open_predicate (const char *filename, gboolean refonly,
+ gboolean load_from_context,
+ MonoAssemblyCandidatePredicate predicate,
+ gpointer user_data,
+ MonoImageOpenStatus *status)
{
MonoImage *image;
MonoAssembly *ass;
}
if (!image)
- image = mono_image_open_full (fname, status, refonly);
+ image = mono_image_open_a_lot (fname, status, refonly, load_from_context);
if (!image){
if (*status == MONO_IMAGE_OK)
return image->assembly;
}
- ass = mono_assembly_load_from_full (image, fname, status, refonly);
+ ass = mono_assembly_load_from_predicate (image, fname, refonly, predicate, user_data, status);
if (ass) {
if (!loaded_from_bundle)
/**
* mono_assembly_load_friends:
- * @ass: an assembly
+ * \param ass an assembly
*
* Load the list of friend assemblies that are allowed to access
* the assembly's internal types and members. They are stored as assembly
/**
* mono_assembly_has_reference_assembly_attribute:
- * @assembly: a MonoAssembly
- * @error: set on error.
+ * \param assembly a MonoAssembly
+ * \param error set on error.
*
- * Returns TRUE if @assembly has the System.Runtime.CompilerServices.ReferenceAssemblyAttribute set.
- * On error returns FALSE and sets @error.
+ * \returns TRUE if \p assembly has the \c System.Runtime.CompilerServices.ReferenceAssemblyAttribute set.
+ * On error returns FALSE and sets \p error.
*/
gboolean
mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error)
/**
* mono_assembly_open:
- * @filename: Opens the assembly pointed out by this name
- * @status: return status code
+ * \param filename Opens the assembly pointed out by this name
+ * \param status return status code
*
- * This loads an assembly from the specified @filename. The @filename allows
- * a local URL (starting with a file:// prefix). If a file prefix is used, the
+ * This loads an assembly from the specified \p filename. The \p filename allows
+ * a local URL (starting with a \c file:// prefix). If a file prefix is used, the
* filename is interpreted as a URL, and the filename is URL-decoded. Otherwise the file
* is treated as a local path.
*
* First, an attempt is made to load the assembly from the bundled executable (for those
- * deployments that have been done with the `mkbundle` tool or for scenarios where the
+ * deployments that have been done with the \c mkbundle tool or for scenarios where the
* assembly has been registered as an embedded assembly). If this is not the case, then
* the assembly is loaded from disk using `api:mono_image_open_full`.
*
* If the pointed assembly does not live in the Global Assembly Cache, a shadow copy of
* the assembly is made.
*
- * Return: a pointer to the MonoAssembly if @filename contains a valid
+ * \returns a pointer to the \c MonoAssembly if \p filename contains a valid
* assembly or NULL on error. Details about the error are stored in the
- * @status variable.
+ * \p status variable.
*/
MonoAssembly *
mono_assembly_open (const char *filename, MonoImageOpenStatus *status)
{
- return mono_assembly_open_full (filename, status, FALSE);
+ return mono_assembly_open_predicate (filename, FALSE, FALSE, NULL, NULL, status);
}
/**
* mono_assembly_load_from_full:
- * @image: Image to load the assembly from
- * @fname: assembly name to associate with the assembly
- * @status: returns the status condition
- * @refonly: Whether this assembly is being opened in "reflection-only" mode.
+ * \param image Image to load the assembly from
+ * \param fname assembly name to associate with the assembly
+ * \param status returns the status condition
+ * \param refonly Whether this assembly is being opened in "reflection-only" mode.
*
- * If the provided @image has an assembly reference, it will process the given
+ * If the provided \p image has an assembly reference, it will process the given
* image as an assembly with the given name.
*
* Most likely you want to use the `api:mono_assembly_load_full` method instead.
*
- * Returns: A valid pointer to a `MonoAssembly*` on success and the @status will be
- * set to #MONO_IMAGE_OK; or NULL on error.
+ * Returns: A valid pointer to a \c MonoAssembly* on success and the \p status will be
+ * set to \c MONO_IMAGE_OK; or NULL on error.
*
- * If there is an error loading the assembly the @status will indicate the
- * reason with @status being set to `MONO_IMAGE_INVALID` if the
+ * If there is an error loading the assembly the \p status will indicate the
+ * reason with \p status being set to \c MONO_IMAGE_INVALID if the
* image did not contain an assembly reference table.
*/
MonoAssembly *
mono_assembly_load_from_full (MonoImage *image, const char*fname,
MonoImageOpenStatus *status, gboolean refonly)
+{
+ return mono_assembly_load_from_predicate (image, fname, refonly, NULL, NULL, status);
+}
+
+MonoAssembly *
+mono_assembly_load_from_predicate (MonoImage *image, const char *fname,
+ gboolean refonly,
+ MonoAssemblyCandidatePredicate predicate,
+ gpointer user_data,
+ MonoImageOpenStatus *status)
{
MonoAssembly *ass, *ass2;
char *base_dir;
mono_error_cleanup (&refasm_error);
}
+ if (predicate && !predicate (ass, user_data)) {
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate returned FALSE, skipping '%s' (%s)\n", ass->aname.name, image->name);
+ g_free (ass);
+ g_free (base_dir);
+ mono_image_close (image);
+ *status = MONO_IMAGE_IMAGE_INVALID;
+ return NULL;
+ }
+
mono_assemblies_lock ();
if (image->assembly) {
/**
* mono_assembly_load_from:
- * @image: Image to load the assembly from
- * @fname: assembly name to associate with the assembly
- * @status: return status code
+ * \param image Image to load the assembly from
+ * \param fname assembly name to associate with the assembly
+ * \param status return status code
*
- * If the provided @image has an assembly reference, it will process the given
+ * If the provided \p image has an assembly reference, it will process the given
* image as an assembly with the given name.
*
* Most likely you want to use the `api:mono_assembly_load_full` method instead.
*
* This is equivalent to calling `api:mono_assembly_load_from_full` with the
- * @refonly parameter set to FALSE.
- * Returns: A valid pointer to a `MonoAssembly*` on success and the @status will be
- * set to #MONO_IMAGE_OK; or NULL on error.
+ * \p refonly parameter set to FALSE.
+ * \returns A valid pointer to a \c MonoAssembly* on success and then \p status will be
+ * set to \c MONO_IMAGE_OK; or NULL on error.
*
- * If there is an error loading the assembly the @status will indicate the
- * reason with @status being set to `MONO_IMAGE_INVALID` if the
+ * If there is an error loading the assembly the \p status will indicate the
+ * reason with \p status being set to \c MONO_IMAGE_INVALID if the
* image did not contain an assembly reference table.
*/
/**
* mono_assembly_name_free:
- * @aname: assembly name to free
+ * \param aname assembly name to free
*
* Frees the provided assembly name object.
* (it does not frees the object itself, only the name members).
/**
* mono_assembly_name_parse:
- * @name: name to parse
- * @aname: the destination assembly name
+ * \param name name to parse
+ * \param aname the destination assembly name
*
* Parses an assembly qualified type name and assigns the name,
* version, culture and token to the provided assembly name object.
*
- * Returns: TRUE if the name could be parsed.
+ * \returns TRUE if the name could be parsed.
*/
gboolean
mono_assembly_name_parse (const char *name, MonoAssemblyName *aname)
/**
* mono_assembly_name_new:
- * @name: name to parse
+ * \param name name to parse
*
- * Allocate a new MonoAssemblyName and fill its values from the
- * passed @name.
+ * Allocate a new \c MonoAssemblyName and fill its values from the
+ * passed \p name.
*
- * Returns: a newly allocated structure or NULL if there was any failure.
+ * \returns a newly allocated structure or NULL if there was any failure.
*/
MonoAssemblyName*
mono_assembly_name_new (const char *name)
return NULL;
}
+/**
+ * mono_assembly_name_get_name:
+ */
const char*
mono_assembly_name_get_name (MonoAssemblyName *aname)
{
return aname->name;
}
+/**
+ * mono_assembly_name_get_culture:
+ */
const char*
mono_assembly_name_get_culture (MonoAssemblyName *aname)
{
return aname->culture;
}
+/**
+ * mono_assembly_name_get_pubkeytoken:
+ */
mono_byte*
mono_assembly_name_get_pubkeytoken (MonoAssemblyName *aname)
{
return NULL;
}
+/**
+ * mono_assembly_name_get_version:
+ */
uint16_t
mono_assembly_name_get_version (MonoAssemblyName *aname, uint16_t *minor, uint16_t *build, uint16_t *revision)
{
if (fullpath == NULL)
return NULL;
else {
- MonoAssembly *res = mono_assembly_open (fullpath, status);
+ MonoAssembly *res = mono_assembly_open_predicate (fullpath, FALSE, FALSE, NULL, NULL, status);
g_free (fullpath);
return res;
}
/**
* mono_assembly_load_with_partial_name:
- * @name: an assembly name that is then parsed by `api:mono_assembly_name_parse`.
- * @status: return status code
+ * \param name an assembly name that is then parsed by `api:mono_assembly_name_parse`.
+ * \param status return status code
*
- * Loads a Mono Assembly from a name. The name is parsed using `api:mono_assembly_name_parse`,
+ * Loads a \c MonoAssembly from a name. The name is parsed using `api:mono_assembly_name_parse`,
* so it might contain a qualified type name, version, culture and token.
*
* This will load the assembly from the file whose name is derived from the assembly name
- * by appending the .dll extension.
+ * by appending the \c .dll extension.
*
* The assembly is loaded from either one of the extra Global Assembly Caches specified
- * by the extra GAC paths (specified by the `MONO_GAC_PREFIX` environment variable) or
+ * by the extra GAC paths (specified by the \c MONO_GAC_PREFIX environment variable) or
* if that fails from the GAC.
*
- * Returns: NULL on failure, or a pointer to a MonoAssembly on success.
+ * \returns NULL on failure, or a pointer to a \c MonoAssembly on success.
*/
MonoAssembly*
mono_assembly_load_with_partial_name (const char *name, MonoImageOpenStatus *status)
if (!domain)
return;
+ if (info->has_new_version && mono_assembly_is_problematic_version (info->name, info->new_version.major, info->new_version.minor, info->new_version.build, info->new_version.revision)) {
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Discarding assembly binding to problematic version %s v%d.%d.%d.%d",
+ info->name, info->new_version.major, info->new_version.minor, info->new_version.build, info->new_version.revision);
+ return;
+ }
+
for (tmp = domain->assembly_bindings; tmp; tmp = tmp->next) {
info_tmp = (MonoAssemblyBindingInfo *)tmp->data;
if (strcmp (info->name, info_tmp->name) == 0 && info_versions_equal (info, info_tmp))
return info;
}
+void
+mono_domain_parse_assembly_bindings (MonoDomain *domain, int amajor, int aminor, gchar *domain_config_file_name)
+{
+ if (domain->assembly_bindings_parsed)
+ return;
+ mono_domain_lock (domain);
+ if (!domain->assembly_bindings_parsed) {
+
+ gchar *domain_config_file_path = mono_portability_find_file (domain_config_file_name, TRUE);
+
+ if (!domain_config_file_path)
+ domain_config_file_path = domain_config_file_name;
+
+ mono_config_parse_assembly_bindings (domain_config_file_path, amajor, aminor, domain, assembly_binding_info_parsed);
+ domain->assembly_bindings_parsed = TRUE;
+ if (domain_config_file_name != domain_config_file_path)
+ g_free (domain_config_file_path);
+ }
+
+ mono_domain_unlock (domain);
+}
+
static MonoAssemblyName*
mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_name)
{
}
if (domain && domain->setup && domain->setup->configuration_file) {
- mono_domain_lock (domain);
- if (!domain->assembly_bindings_parsed) {
- gchar *domain_config_file_name = mono_string_to_utf8_checked (domain->setup->configuration_file, &error);
- /* expect this to succeed because mono_domain_set_options_from_config () did
- * the same thing when the domain was created. */
- mono_error_assert_ok (&error);
-
- gchar *domain_config_file_path = mono_portability_find_file (domain_config_file_name, TRUE);
-
- if (!domain_config_file_path)
- domain_config_file_path = domain_config_file_name;
-
- mono_config_parse_assembly_bindings (domain_config_file_path, aname->major, aname->minor, domain, assembly_binding_info_parsed);
- domain->assembly_bindings_parsed = TRUE;
- if (domain_config_file_name != domain_config_file_path)
- g_free (domain_config_file_name);
- g_free (domain_config_file_path);
- }
+ gchar *domain_config_file_name = mono_string_to_utf8_checked (domain->setup->configuration_file, &error);
+ /* expect this to succeed because mono_domain_set_options_from_config () did
+ * the same thing when the domain was created. */
+ mono_error_assert_ok (&error);
+ mono_domain_parse_assembly_bindings (domain, aname->major, aname->minor, domain_config_file_name);
+ g_free (domain_config_file_name);
+ mono_domain_lock (domain);
info2 = get_per_domain_assembly_binding_info (domain, aname);
if (info2) {
}
mono_domain_unlock (domain);
+
}
if (!info) {
/**
* mono_assembly_load_from_gac
*
- * @aname: The assembly name object
+ * \param aname The assembly name object
*/
static MonoAssembly*
mono_assembly_load_from_gac (MonoAssemblyName *aname, gchar *filename, MonoImageOpenStatus *status, MonoBoolean refonly)
paths = extra_gac_paths;
while (!result && *paths) {
fullpath = g_build_path (G_DIR_SEPARATOR_S, *paths, "lib", "mono", "gac", subpath, NULL);
- result = mono_assembly_open_full (fullpath, status, refonly);
+ result = mono_assembly_open_predicate (fullpath, refonly, FALSE, NULL, NULL, status);
g_free (fullpath);
paths++;
}
fullpath = g_build_path (G_DIR_SEPARATOR_S, mono_assembly_getrootdir (),
"mono", "gac", subpath, NULL);
- result = mono_assembly_open_full (fullpath, status, refonly);
+ result = mono_assembly_open_predicate (fullpath, refonly, FALSE, NULL, NULL, status);
g_free (fullpath);
if (result)
// This unusual directory layout can occur if mono is being built and run out of its own source repo
if (assemblies_path) { // Custom assemblies path set via MONO_PATH or mono_set_assemblies_path
- corlib = load_in_path ("mscorlib.dll", (const char**)assemblies_path, status, FALSE);
+ corlib = load_in_path ("mscorlib.dll", (const char**)assemblies_path, status, FALSE, NULL, NULL);
if (corlib)
goto return_corlib_and_facades;
}
/* Normal case: Load corlib from mono/<version> */
corlib_file = g_build_filename ("mono", runtime->framework_version, "mscorlib.dll", NULL);
if (assemblies_path) { // Custom assemblies path
- corlib = load_in_path (corlib_file, (const char**)assemblies_path, status, FALSE);
+ corlib = load_in_path (corlib_file, (const char**)assemblies_path, status, FALSE, NULL, NULL);
if (corlib) {
g_free (corlib_file);
goto return_corlib_and_facades;
}
}
- corlib = load_in_path (corlib_file, default_path, status, FALSE);
+ corlib = load_in_path (corlib_file, default_path, status, FALSE, NULL, NULL);
g_free (corlib_file);
return_corlib_and_facades:
- if (corlib && !strcmp (runtime->framework_version, "4.5")) // FIXME: stop hardcoding 4.5 here
+ if (corlib)
default_path [1] = g_strdup_printf ("%s/Facades", corlib->basedir);
return corlib;
return candidate;
}
+gboolean
+mono_assembly_candidate_predicate_sn_same_name (MonoAssembly *candidate, gpointer ud)
+{
+ MonoAssemblyName *wanted_name = (MonoAssemblyName*)ud;
+ MonoAssemblyName *candidate_name = &candidate->aname;
+
+ g_assert (wanted_name != NULL);
+ g_assert (candidate_name != NULL);
+
+ if (mono_trace_is_traced (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY)) {
+ char * s = mono_stringify_assembly_name (wanted_name);
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: wanted = %s\n", s);
+ g_free (s);
+ s = mono_stringify_assembly_name (candidate_name);
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate = %s\n", s);
+ g_free (s);
+ }
+
+
+ /* Wanted name has no token, not strongly named: always matches. */
+ if (0 == wanted_name->public_key_token [0]) {
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: wanted has no token, returning TRUE\n");
+ return TRUE;
+ }
+
+ /* Candidate name has no token, not strongly named: never matches */
+ if (0 == candidate_name->public_key_token [0]) {
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate has no token, returning FALSE\n");
+ return FALSE;
+ }
+
+ return exact_sn_match (wanted_name, candidate_name) ||
+ framework_assembly_sn_match (wanted_name, candidate_name);
+}
+
+gboolean
+exact_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *candidate_name)
+{
+ gboolean result = mono_assembly_names_equal (wanted_name, candidate_name);
+
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s\n",
+ result ? "match, returning TRUE" : "don't match, returning FALSE");
+ return result;
+
+}
+
+gboolean
+framework_assembly_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *candidate_name)
+{
+#ifndef DISABLE_ASSEMBLY_REMAPPING
+ const AssemblyVersionMap *vmap = (AssemblyVersionMap *)g_hash_table_lookup (assembly_remapping_table, wanted_name->name);
+ if (vmap) {
+ if (!vmap->framework_facade_assembly) {
+ /* If the wanted name is a framework assembly, it's enough for the name/version/culture to match. If the assembly was remapped, the public key token is likely unrelated. */
+ gboolean result = assembly_names_equal_flags (wanted_name, candidate_name, ANAME_EQ_IGNORE_PUBKEY);
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s (ignoring the public key token)", result ? "match, returning TRUE" : "don't match, returning FALSE");
+ return result;
+ } else {
+ /* For facades, the name and public key token should
+ * match, but the version doesn't matter. */
+ gboolean result = assembly_names_equal_flags (wanted_name, candidate_name, ANAME_EQ_IGNORE_VERSION);
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s (ignoring version)", result ? "match, returning TRUE" : "don't match, returning FALSE");
+ return result;
+ }
+ }
+#endif
+ return FALSE;
+}
MonoAssembly*
mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
int len;
aname = mono_assembly_remap_version (aname, &maped_aname);
-
+
/* Reflection only assemblies don't get assembly binding */
if (!refonly)
aname = mono_assembly_apply_binding (aname, &maped_name_pp);
return mono_assembly_load_corlib (mono_get_runtime_info (), status);
}
+ MonoAssemblyCandidatePredicate predicate = NULL;
+ void* predicate_ud = NULL;
+#if !defined(DISABLE_STRICT_STRONG_NAMES)
+ if (G_LIKELY (mono_loader_get_strict_strong_names ())) {
+ predicate = &mono_assembly_candidate_predicate_sn_same_name;
+ predicate_ud = aname;
+ }
+#endif
+
len = strlen (aname->name);
for (ext_index = 0; ext_index < 2; ext_index ++) {
ext = ext_index == 0 ? ".dll" : ".exe";
if (basedir) {
fullpath = g_build_filename (basedir, filename, NULL);
- result = mono_assembly_open_full (fullpath, status, refonly);
+ result = mono_assembly_open_predicate (fullpath, refonly, FALSE, predicate, predicate_ud, status);
g_free (fullpath);
if (result) {
result->in_gac = FALSE;
}
}
- result = load_in_path (filename, default_path, status, refonly);
+ result = load_in_path (filename, default_path, status, refonly, predicate, predicate_ud);
if (result)
result->in_gac = FALSE;
g_free (filename);
/**
* mono_assembly_load_full:
- * @aname: A MonoAssemblyName with the assembly name to load.
- * @basedir: A directory to look up the assembly at.
- * @status: a pointer to a MonoImageOpenStatus to return the status of the load operation
- * @refonly: Whether this assembly is being opened in "reflection-only" mode.
+ * \param aname A MonoAssemblyName with the assembly name to load.
+ * \param basedir A directory to look up the assembly at.
+ * \param status a pointer to a MonoImageOpenStatus to return the status of the load operation
+ * \param refonly Whether this assembly is being opened in "reflection-only" mode.
*
- * Loads the assembly referenced by @aname, if the value of @basedir is not NULL, it
+ * Loads the assembly referenced by \p aname, if the value of \p basedir is not NULL, it
* attempts to load the assembly from that directory before probing the standard locations.
*
- * If the assembly is being opened in reflection-only mode (@refonly set to TRUE) then no
+ * If the assembly is being opened in reflection-only mode (\p refonly set to TRUE) then no
* assembly binding takes place.
*
- * Returns: the assembly referenced by @aname loaded or NULL on error. On error the
- * value pointed by status is updated with an error code.
+ * \returns the assembly referenced by \p aname loaded or NULL on error. On error the
+ * value pointed by \p status is updated with an error code.
*/
MonoAssembly*
mono_assembly_load_full (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status, gboolean refonly)
/**
* mono_assembly_load:
- * @aname: A MonoAssemblyName with the assembly name to load.
- * @basedir: A directory to look up the assembly at.
- * @status: a pointer to a MonoImageOpenStatus to return the status of the load operation
+ * \param aname A MonoAssemblyName with the assembly name to load.
+ * \param basedir A directory to look up the assembly at.
+ * \param status a pointer to a MonoImageOpenStatus to return the status of the load operation
*
- * Loads the assembly referenced by @aname, if the value of @basedir is not NULL, it
+ * Loads the assembly referenced by \p aname, if the value of \p basedir is not NULL, it
* attempts to load the assembly from that directory before probing the standard locations.
*
- * Returns: the assembly referenced by @aname loaded or NULL on error. On error the
- * value pointed by status is updated with an error code.
+ * \returns the assembly referenced by \p aname loaded or NULL on error. On error the
+ * value pointed by \p status is updated with an error code.
*/
MonoAssembly*
mono_assembly_load (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status)
/**
* mono_assembly_loaded_full:
- * @aname: an assembly to look for.
- * @refonly: Whether this assembly is being opened in "reflection-only" mode.
+ * \param aname an assembly to look for.
+ * \param refonly Whether this assembly is being opened in "reflection-only" mode.
*
* This is used to determine if the specified assembly has been loaded
- * Returns: NULL If the given @aname assembly has not been loaded, or a pointer to
- * a `MonoAssembly` that matches the `MonoAssemblyName` specified.
+ * \returns NULL If the given \p aname assembly has not been loaded, or a pointer to
+ * a \c MonoAssembly that matches the \c MonoAssemblyName specified.
*/
MonoAssembly*
mono_assembly_loaded_full (MonoAssemblyName *aname, gboolean refonly)
/**
* mono_assembly_loaded:
- * @aname: an assembly to look for.
+ * \param aname an assembly to look for.
*
* This is used to determine if the specified assembly has been loaded
- * Returns: NULL If the given @aname assembly has not been loaded, or a pointer to
- * a `MonoAssembly` that matches the `MonoAssemblyName` specified.
+ * \returns NULL If the given \p aname assembly has not been loaded, or a pointer to
+ * a \c MonoAssembly that matches the \c MonoAssemblyName specified.
*/
MonoAssembly*
mono_assembly_loaded (MonoAssemblyName *aname)
/**
* mono_assembly_close:
- * @assembly: the assembly to release.
+ * \param assembly the assembly to release.
*
- * This method releases a reference to the @assembly. The assembly is
+ * This method releases a reference to the \p assembly. The assembly is
* only released when all the outstanding references to it are released.
*/
void
mono_assembly_close_finish (assembly);
}
+/**
+ * mono_assembly_load_module:
+ */
MonoImage*
mono_assembly_load_module (MonoAssembly *assembly, guint32 idx)
{
/**
* mono_assembly_foreach:
- * @func: function to invoke for each assembly loaded
- * @user_data: data passed to the callback
+ * \param func function to invoke for each assembly loaded
+ * \param user_data data passed to the callback
*
- * Invokes the provided @func callback for each assembly loaded into
+ * Invokes the provided \p func callback for each assembly loaded into
* the runtime. The first parameter passed to the callback is the
- * `MonoAssembly*`, and the second parameter is the @user_data.
+ * \c MonoAssembly*, and the second parameter is the \p user_data.
*
* This is done for all assemblies loaded in the runtime, not just
* those loaded in the current application domain.
*/
static MonoAssembly *main_assembly=NULL;
+/**
+ * mono_assembly_set_main:
+ */
void
mono_assembly_set_main (MonoAssembly *assembly)
{
/**
* mono_assembly_get_image:
- * @assembly: The assembly to retrieve the image from
+ * \param assembly The assembly to retrieve the image from
*
- * Returns: the MonoImage associated with this assembly.
+ * \returns the \c MonoImage associated with this assembly.
*/
MonoImage*
mono_assembly_get_image (MonoAssembly *assembly)
/**
* mono_assembly_get_name:
- * @assembly: The assembly to retrieve the name from
+ * \param assembly The assembly to retrieve the name from
*
- * The returned name's lifetime is the same as @assembly's.
+ * The returned name's lifetime is the same as \p assembly's.
*
- * Returns: the MonoAssemblyName associated with this assembly.
+ * \returns the \c MonoAssemblyName associated with this assembly.
*/
MonoAssemblyName *
mono_assembly_get_name (MonoAssembly *assembly)
return &assembly->aname;
}
+/**
+ * mono_register_bundled_assemblies:
+ */
void
mono_register_bundled_assemblies (const MonoBundledAssembly **assemblies)
{