return NULL;
}
+static gchar *
+canonicalize_path (const char *path)
+{
+ gchar *abspath, *pos, *lastpos, *dest;
+ int backc;
+
+ if (g_path_is_absolute (path)) {
+ abspath = g_strdup (path);
+ } else {
+ gchar *tmpdir = g_get_current_dir ();
+ abspath = g_build_filename (tmpdir, path, NULL);
+ g_free (tmpdir);
+ }
+
+ abspath = g_strreverse (abspath);
+
+ backc = 0;
+ dest = lastpos = abspath;
+ pos = strchr (lastpos, G_DIR_SEPARATOR);
+
+ while (pos != NULL) {
+ int len = pos - lastpos;
+ if (len == 1 && lastpos [0] == '.') {
+ // nop
+ } else if (len == 2 && lastpos [0] == '.' && lastpos [1] == '.') {
+ backc++;
+ } else if (len > 0) {
+ if (backc > 0) {
+ backc--;
+ } else {
+ if (dest != lastpos) strncpy (dest, lastpos, len + 1);
+ dest += len + 1;
+ }
+ }
+ lastpos = pos + 1;
+ pos = strchr (lastpos, G_DIR_SEPARATOR);
+ }
+
+ if (dest != lastpos) strcpy (dest, lastpos);
+ return g_strreverse (abspath);
+}
+
/**
* mono_images_init:
*
t = &image->tables [MONO_TABLE_MODULEREF];
image->modules = g_new0 (MonoImage *, t->rows);
+ image->module_count = t->rows;
base_dir = g_path_get_dirname (image->name);
for (i = 0; i < t->rows; i++){
char *module_ref;
image->native_wrapper_cache = g_hash_table_new (NULL, NULL);
image->remoting_invoke_cache = g_hash_table_new (NULL, NULL);
image->synchronized_cache = g_hash_table_new (NULL, NULL);
+ image->unbox_wrapper_cache = g_hash_table_new (NULL, NULL);
image->typespec_cache = g_hash_table_new (NULL, NULL);
image->memberref_signatures = g_hash_table_new (NULL, NULL);
image->helper_signatures = g_hash_table_new (g_str_hash, g_str_equal);
-
- image->generic_inst_cache =
- g_hash_table_new ((GHashFunc)mono_metadata_generic_inst_hash,
- (GCompareFunc)mono_metadata_generic_inst_equal);
}
static MonoImage *
image->f = filed;
iinfo = g_new0 (MonoCLIImageInfo, 1);
image->image_info = iinfo;
-
- if (g_path_is_absolute (fname))
- image->name = g_strdup (fname);
- else {
- gchar *path = g_get_current_dir ();
- image->name = g_build_filename (path, fname, NULL);
- g_free (path);
- }
+ image->name = canonicalize_path (fname);
return do_mono_image_load (image, status);
}
g_return_val_if_fail (fname != NULL, NULL);
- if (g_path_is_absolute (fname))
- absfname = (char*)fname;
- else {
- gchar *path = g_get_current_dir ();
- absfname = g_build_filename (path, fname, NULL);
- g_free (path);
- }
+ absfname = canonicalize_path (fname);
/*
* The easiest solution would be to do all the loading inside the mutex,
*/
EnterCriticalSection (&images_mutex);
image = g_hash_table_lookup (loaded_images_hash, absfname);
-
- if (absfname != fname)
- g_free (absfname);
+ g_free (absfname);
if (image){
image->ref_count++;
return NULL;
EnterCriticalSection (&images_mutex);
- image2 = g_hash_table_lookup (loaded_images_hash, fname);
+ image2 = g_hash_table_lookup (loaded_images_hash, image->name);
+
if (image2) {
/* Somebody else beat us to it */
image2->ref_count ++;
LeaveCriticalSection (&images_mutex);
mono_image_close (image);
-
return image2;
}
g_hash_table_insert (loaded_images_hash, image->name, image);
- if (image->assembly_name)
+ if (image->assembly_name && (g_hash_table_lookup (loaded_images_hash, image->assembly_name) == NULL))
g_hash_table_insert (loaded_images_hash, (char *) image->assembly_name, image);
g_hash_table_insert (loaded_images_guid_hash, image->guid, image);
LeaveCriticalSection (&images_mutex);
mono_metadata_free_method_signature ((MonoMethodSignature*)val);
}
+static void
+free_remoting_wrappers (gpointer key, gpointer val, gpointer user_data)
+{
+ g_free (val);
+}
+
/**
* mono_image_addref:
* @image: The image file we wish to add a reference to
if (image == image2) {
/* This is not true if we are called from mono_image_open () */
g_hash_table_remove (loaded_images_hash, image->name);
- if (image->assembly_name)
- g_hash_table_remove (loaded_images_hash, (char *) image->assembly_name);
g_hash_table_remove (loaded_images_guid_hash, image->guid);
/* Multiple images might have the same guid */
build_guid_table ();
- }
+ }
+ if (image->assembly_name && (g_hash_table_lookup (loaded_images_hash, image->assembly_name) == image))
+ g_hash_table_remove (loaded_images_hash, (char *) image->assembly_name);
LeaveCriticalSection (&images_mutex);
if (image->f)
g_free (image->raw_data);
}
g_free (image->name);
+ g_free (image->guid);
g_free (image->files);
g_hash_table_destroy (image->method_cache);
g_hash_table_destroy (image->delegate_begin_invoke_cache);
g_hash_table_destroy (image->delegate_end_invoke_cache);
g_hash_table_destroy (image->delegate_invoke_cache);
+ g_hash_table_foreach (image->remoting_invoke_cache, free_remoting_wrappers, NULL);
g_hash_table_destroy (image->remoting_invoke_cache);
g_hash_table_destroy (image->runtime_invoke_cache);
+ g_hash_table_destroy (image->synchronized_cache);
+ g_hash_table_destroy (image->unbox_wrapper_cache);
g_hash_table_destroy (image->typespec_cache);
- g_hash_table_destroy (image->generic_inst_cache);
g_hash_table_foreach (image->memberref_signatures, free_mr_signatures, NULL);
g_hash_table_destroy (image->memberref_signatures);
g_hash_table_foreach (image->helper_signatures, free_mr_signatures, NULL);
res = mono_image_open (name, NULL);
if (res) {
int i;
- t = &res->tables [MONO_TABLE_MODULEREF];
/* g_print ("loaded file %s from %s (%p)\n", name, image->name, image->assembly); */
res->assembly = image->assembly;
- for (i = 0; i < t->rows; ++i) {
+ for (i = 0; i < res->module_count; ++i) {
if (res->modules [i] && !res->modules [i]->assembly)
res->modules [i]->assembly = image->assembly;
}
}
int
-mono_table_info_get_rows (MonoTableInfo *table)
+mono_table_info_get_rows (const MonoTableInfo *table)
{
return table->rows;
}
return image->dynamic;
}
-
+gboolean
+mono_image_has_authenticode_entry (MonoImage *image)
+{
+ MonoCLIImageInfo *iinfo = image->image_info;
+ MonoDotNetHeader *header = &iinfo->cli_header;
+ MonoPEDirEntry *de = &header->datadir.pe_certificate_table;
+ // the Authenticode "pre" (non ASN.1) header is 8 bytes long
+ return ((de->rva != 0) && (de->size > 8));
+}