Hi,

I also modified Makefile to export __stdcall functions without mangling and
create-windef.pl to include MonoFixupCorEE. Other than these there are no
modifications.

Kornél

----- Original Message ----- From: Kornél Pál
To: mono-devel; Robert Jordan
Sent: Wednesday, April 23, 2008 2:40 PM
Subject: Re: [Mono-dev] [PATCH] Add mixed-mode assembly support on Windows
(now build with cygwin as well)


From: Robert Jordan
I think the following code is from another patch set (the cmd line
encoding issue you sent a patch for). Is it complete?
Index: mono/mono/mini/main.c

Yes, it is. I included it in this patch to be consistent with _CorExeMain
implementation. Also note that command line arguments are parsed as UTF-8
without MONO_EXTERNAL_ENCODINGS. MONO_EXTERNAL_ENCODINGS should not be
supported on Windows, Unicode API should be used instead. Patching main
will
make Mono support non-ASCII command line arguments on Windows. Also note
that because images are loaded using LoadLibrary file names are expected
to
be in UTF-8 that is supported by this main function patch.  I still would
vote for removing MONO_EXTERNAL_ENCODINGS support on Windows but that is
out
of the scope of this patch.

If this is solved, I will try to fix the cygwin build.

I managed to fix the build. #include <config.h> had to be moved out of
#ifdef PLATFORM_WIN32 because PLATFORM_WIN32 is defined in config.h in the
cygwin build.

Please review the patch. Please try it on Linux as well to make sure that
it
doesn't break Linux. And if you like it, please approve the patch.

Kornél

Index: mono/libgc/win32_threads.c
===================================================================
--- mono/libgc/win32_threads.c  (revision 101236)
+++ mono/libgc/win32_threads.c  (working copy)
@@ -782,7 +782,7 @@
 * Pontus Rydin suggests wrapping the thread start routine instead.
 */
#if defined(GC_DLL) || defined(GC_INSIDE_DLL)
-BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
+BOOL WINAPI GC_DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
{
  switch (reason) {
  case DLL_PROCESS_ATTACH:
Index: mono/libgc/include/gc.h
===================================================================
--- mono/libgc/include/gc.h     (revision 101236)
+++ mono/libgc/include/gc.h     (working copy)
@@ -922,6 +922,8 @@
#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
# include <windows.h>

+   BOOL WINAPI GC_DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved);
+
  /*
   * All threads must be created using GC_CreateThread, so that they will be
   * recorded in the thread table.  For backwards compatibility, this is not
Index: mono/mono/metadata/loader.c
===================================================================
--- mono/mono/metadata/loader.c (revision 101236)
+++ mono/mono/metadata/loader.c (working copy)
@@ -1394,12 +1394,20 @@
        if (cols [1] & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
                if (result->klass == mono_defaults.string_class && !strcmp (result->name, 
".ctor"))
                        result->string_ctor = 1;
-       } else if ((cols [2] & METHOD_ATTRIBUTE_PINVOKE_IMPL) && (!(cols [1] & 
METHOD_IMPL_ATTRIBUTE_NATIVE))) {
+       } else if (cols [2] & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
                MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)result;
-               MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];

+#ifdef PLATFORM_WIN32
+               /* IJW is P/Invoke with a predefined function pointer */
+               if (image->is_module_handle && (cols [1] & 
METHOD_IMPL_ATTRIBUTE_NATIVE)) {
+                       piinfo->addr = mono_image_rva_map (image, cols [0]);
+                       g_assert (piinfo->addr);
+               }
+#endif
                piinfo->implmap_idx = mono_metadata_implmap_from_method (image, 
idx - 1);
-               piinfo->piflags = mono_metadata_decode_row_col (im, 
piinfo->implmap_idx - 1, MONO_IMPLMAP_FLAGS);
+               /* native methods can have no map */
+               if (piinfo->implmap_idx)
+                       piinfo->piflags = mono_metadata_decode_row_col (&tables 
[MONO_TABLE_IMPLMAP], piinfo->implmap_idx - 1, MONO_IMPLMAP_FLAGS);
        }

        /* FIXME: lazyness for generics too, but how? */
@@ -1900,7 +1908,7 @@

        if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
                m->signature->pinvoke = 1;
-       else if ((m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) && (!(m->iflags & 
METHOD_IMPL_ATTRIBUTE_NATIVE))) {
+       else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
                MonoCallConvention conv = 0;
                MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)m;
                m->signature->pinvoke = 1;
Index: mono/mono/metadata/domain.c
===================================================================
--- mono/mono/metadata/domain.c (revision 101236)
+++ mono/mono/metadata/domain.c (working copy)
@@ -34,9 +34,14 @@
#include <mono/metadata/threads-types.h>
#include <metadata/threads.h>
#include <metadata/profiler-private.h>
+#include <mono/metadata/coree.h>

/* #define DEBUG_DOMAIN_UNLOAD */

+#ifdef PLATFORM_WIN32
+extern HMODULE coree_handle;
+#endif
+
/* we need to use both the Tls* functions and __thread because
 * some archs may generate faster jit code with one meachanism
 * or the other (we used to do it because tls slots were GC-tracked,
@@ -1160,6 +1165,15 @@
        if (domain)
                g_assert_not_reached ();

+#if defined(PLATFORM_WIN32) && !defined(_WIN64)
+       /* Fixup exported functions of mscoree.dll to our implementations. */
+       coree_handle = LoadLibrary (L"mscoree.dll");
+       if (coree_handle && !SUCCEEDED (MonoFixupCorEE (coree_handle))) {
+               FreeLibrary (coree_handle);
+               coree_handle = NULL;
+       }
+#endif
+
        mono_perfcounters_init ();

        mono_counters_register ("Max native code in a domain", 
MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_size);
@@ -1196,6 +1210,11 @@
                 * exe_image, and close it during shutdown.
                 */
                get_runtimes_from_exe (exe_filename, &exe_image, runtimes);
+#ifdef PLATFORM_WIN32
+               /* Executable images are only mapped by the OS loader we need 
to do fixups for native code support. */
+               if (exe_image && exe_image->is_module_handle && (HMODULE) 
exe_image->raw_data != GetModuleHandle (NULL))
+                       MonoFixupExe ((HMODULE) exe_image->raw_data);
+#endif
        } else if (runtime_version != NULL) {
                runtimes [0] = get_runtime_by_version (runtime_version);
                runtimes [1] = NULL;
Index: mono/mono/metadata/appdomain.c
===================================================================
--- mono/mono/metadata/appdomain.c      (revision 101236)
+++ mono/mono/metadata/appdomain.c      (working copy)
@@ -92,6 +92,21 @@
static void
mono_domain_unload (MonoDomain *domain);

+static MonoLoadFunc load_function = NULL;
+
+void
+mono_install_runtime_load (MonoLoadFunc func)
+{
+       load_function = func;
+}
+
+MonoDomain*
+mono_runtime_load (const char *filename, const char *runtime_version)
+{
+       g_assert (load_function);
+       return load_function (filename, runtime_version);
+}
+
/**
 * mono_runtime_init:
 * @domain: domain returned by mono_init ()
Index: mono/mono/metadata/appdomain.h
===================================================================
--- mono/mono/metadata/appdomain.h      (revision 101236)
+++ mono/mono/metadata/appdomain.h      (working copy)
@@ -25,9 +25,17 @@
typedef struct _MonoAppDomain MonoAppDomain;
typedef struct _MonoJitInfo MonoJitInfo;

+typedef MonoDomain* (*MonoLoadFunc) (const char *filename, const char 
*runtime_version);
+
typedef void (*MonoDomainFunc) (MonoDomain *domain, gpointer user_data);

+void
+mono_install_runtime_load  (MonoLoadFunc func);
+
MonoDomain*
+mono_runtime_load          (const char *filename, const char *runtime_version);
+
+MonoDomain*
mono_init                  (const char *filename);

MonoDomain *
Index: mono/mono/metadata/assembly.c
===================================================================
--- mono/mono/metadata/assembly.c       (revision 101236)
+++ mono/mono/metadata/assembly.c       (working copy)
@@ -574,6 +574,11 @@
 * Registers the root directory for the Mono runtime, for Linux and Solaris 10,
* this auto-detects the prefix where Mono was installed. */
+
+#ifdef PLATFORM_WIN32
+HMODULE mono_module_handle;
+#endif
+
void
mono_set_rootdir (void)
{
@@ -581,7 +586,7 @@
        gunichar2 moddir [MAXPATHLEN];
        gchar *bindir, *installdir, *root, *utf8name, *config;

-       GetModuleFileNameW (NULL, moddir, MAXPATHLEN);
+       GetModuleFileNameW (mono_module_handle, moddir, MAXPATHLEN);
        utf8name = g_utf16_to_utf8 (moddir, -1, NULL, NULL, NULL);
        bindir = g_path_get_dirname (utf8name);
        installdir = g_path_get_dirname (bindir);
@@ -1477,6 +1482,10 @@
        loaded_assemblies = g_list_prepend (loaded_assemblies, ass);
        if (mono_defaults.internals_visible_class)
                mono_assembly_load_friends (ass);
+#ifdef PLATFORM_WIN32
+       if (image->is_module_handle)
+               mono_image_fixup_vtable (image);
+#endif
        mono_assemblies_unlock ();

        mono_assembly_invoke_load_hook (ass);
Index: mono/mono/metadata/image.c
===================================================================
--- mono/mono/metadata/image.c  (revision 101236)
+++ mono/mono/metadata/image.c  (working copy)
@@ -39,6 +39,10 @@

#define INVALID_ADDRESS 0xffffffff

+#ifdef PLATFORM_WIN32
+HMODULE coree_handle = NULL;
+#endif
+
/*
 * Keeps track of the various assemblies loaded
 */
@@ -51,9 +55,11 @@
#define mono_images_unlock() LeaveCriticalSection (&images_mutex)
static CRITICAL_SECTION images_mutex;

+/* returns offset relative to image->raw_data */
guint32
-mono_cli_rva_image_map (MonoCLIImageInfo *iinfo, guint32 addr)
+mono_cli_rva_image_map (MonoImage *image, guint32 addr)
{
+       MonoCLIImageInfo *iinfo = image->image_info;
        const int top = iinfo->cli_section_count;
        MonoSectionTable *tables = iinfo->cli_section_tables;
        int i;
@@ -61,6 +67,10 @@
        for (i = 0; i < top; i++){
                if ((addr >= tables->st_virtual_address) &&
                    (addr < tables->st_virtual_address + 
tables->st_raw_data_size)){
+#ifdef PLATFORM_WIN32
+                       if (image->is_module_handle)
+                               return addr;
+#endif
                        return addr - tables->st_virtual_address + 
tables->st_raw_data_ptr;
                }
                tables++;
@@ -94,6 +104,10 @@
                                if (!mono_image_ensure_section_idx (image, i))
                                        return NULL;
                        }
+#ifdef PLATFORM_WIN32
+                       if (image->is_module_handle)
+                               return image->raw_data + addr;
+#endif
                        return (char*)iinfo->cli_sections [i] +
                                (addr - tables->st_virtual_address);
                }
@@ -160,6 +174,11 @@

        if (sect->st_raw_data_ptr + sect->st_raw_data_size > 
image->raw_data_len)
                return FALSE;
+#ifdef PLATFORM_WIN32
+       if (image->is_module_handle)
+               iinfo->cli_sections [section] = image->raw_data + 
sect->st_virtual_address;
+       else
+#endif
        /* FIXME: we ignore the writable flag since we don't patch the binary */
        iinfo->cli_sections [section] = image->raw_data + sect->st_raw_data_ptr;
        return TRUE;
@@ -230,7 +249,7 @@
{
        guint32 offset;
        
-       offset = mono_cli_rva_image_map (iinfo, 
iinfo->cli_header.datadir.pe_cli_header.rva);
+       offset = mono_cli_rva_image_map (image, 
iinfo->cli_header.datadir.pe_cli_header.rva);
        if (offset == INVALID_ADDRESS)
                return FALSE;

@@ -298,7 +317,7 @@
        guint32 pad;
        char *ptr;
        
-       offset = mono_cli_rva_image_map (iinfo, 
iinfo->cli_cli_header.ch_metadata.rva);
+       offset = mono_cli_rva_image_map (image, 
iinfo->cli_cli_header.ch_metadata.rva);
        if (offset == INVALID_ADDRESS)
                return FALSE;

@@ -546,6 +565,10 @@
                        if (image->modules [idx - 1]) {
                                mono_image_addref (image->modules [idx - 1]);
                                image->modules [idx - 1]->assembly = 
image->assembly;
+#ifdef PLATFORM_WIN32
+                               if (image->modules [idx - 1]->is_module_handle)
+                                       mono_image_fixup_vtable (image->modules 
[idx - 1]);
+#endif
                                /* g_print ("loaded module %s from %s (%p)\n", 
module_ref, image->name, image->assembly); */
                        }
                        g_free (module_ref);
@@ -642,6 +665,9 @@
{
        MonoDotNetHeader64 header64;

+#ifdef PLATFORM_WIN32
+       if (!image->is_module_handle)
+#endif
        if (offset + sizeof (MonoDotNetHeader32) > image->raw_data_len)
                return -1;

@@ -760,6 +786,11 @@
        SWAPPDE (header->datadir.pe_cli_header);
        SWAPPDE (header->datadir.pe_reserved);

+#ifdef PLATFORM_WIN32
+       if (image->is_module_handle)
+               image->raw_data_len = header->nt.pe_image_size;
+#endif
+
        return offset;
}

@@ -782,6 +813,9 @@
        if (status)
                *status = MONO_IMAGE_IMAGE_INVALID;

+#ifdef PLATFORM_WIN32
+       if (!image->is_module_handle)
+#endif
        if (offset + sizeof (msdos) > image->raw_data_len)
                goto invalid_image;
        memcpy (&msdos, image->raw_data + offset, sizeof (msdos));
@@ -995,6 +1029,16 @@
                g_hash_table_insert (loaded_images, (char *) 
image->assembly_name, image);   
        mono_images_unlock ();

+#ifdef PLATFORM_WIN32
+       if (image->is_module_handle && image->raw_data) {
+               guint16* fname_utf16;
+
+               fname_utf16 = g_utf8_to_utf16 (image->name, -1, NULL, NULL, 
NULL);
+               LoadLibrary (fname_utf16);
+               g_free (fname_utf16);
+       }
+#endif
+
        return image;
}

@@ -1072,6 +1116,38 @@
        }
        mono_images_unlock ();

+#ifdef PLATFORM_WIN32
+       /* Load modules using LoadLibrary */
+       if (!refonly && coree_handle) {
+               MonoCLIImageInfo *iinfo;
+               HMODULE module_handle;
+               guint16* fname_utf16;
+
+               fname_utf16 = g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL);
+               module_handle = LoadLibrary (fname_utf16);
+               g_free (fname_utf16);
+
+               if (module_handle == NULL) {
+                       if (status)
+                               *status = MONO_IMAGE_ERROR_ERRNO;
+                       return NULL;
+               }
+
+               image = g_new0 (MonoImage, 1);
+               image->raw_data = (char*) module_handle;
+               image->is_module_handle = TRUE;
+               iinfo = g_new0 (MonoCLIImageInfo, 1);
+               image->image_info = iinfo;
+               image->name = mono_path_resolve_symlinks (fname);
+               image->ref_count = 1;
+
+               image = do_mono_image_load (image, status, TRUE);
+               image = register_image (image);
+               FreeLibrary (module_handle);
+               return image;
+       }
+#endif
+
        image = do_mono_image_open (fname, status, TRUE, refonly);
        if (image == NULL)
                return NULL;
@@ -1114,6 +1190,57 @@
        return(do_mono_image_open (fname, status, FALSE, FALSE));
}

+void
+mono_image_fixup_vtable (MonoImage *image)
+{
+#ifdef PLATFORM_WIN32
+       MonoCLIImageInfo *iinfo;
+       MonoPEDirEntry *de;
+       MonoVTableFixup *vtfixup;
+       int count;
+       gpointer slot;
+       guint16 slot_type;
+       int slot_count;
+
+       g_assert (image->is_module_handle);
+
+       iinfo = image->image_info;
+       de = &iinfo->cli_cli_header.ch_vtable_fixups;
+       if (!de->rva || !de->size)
+               return;
+       vtfixup = (MonoVTableFixup*) mono_image_rva_map (image, de->rva);
+       if (!vtfixup)
+               return;
+       
+       count = de->size / sizeof (MonoVTableFixup);
+       while (count--) {
+               if (!vtfixup->rva || !vtfixup->count)
+                       continue;
+
+               slot = mono_image_rva_map (image, vtfixup->rva);
+               g_assert (slot);
+               slot_type = vtfixup->type;
+               slot_count = vtfixup->count;
+               if (slot_type & VTFIXUP_TYPE_32BIT)
+                       while (slot_count--) {
+                               *((guint32*) slot) = 
mono_marshal_get_vtfixup_ftnptr (image, *((guint32*) slot), slot_type);
+                               ((guint32*) slot)++;
+                       }
+               else if (slot_type & VTFIXUP_TYPE_64BIT)
+                       while (slot_count--) {
+                               *((guint64*) slot) = 
mono_marshal_get_vtfixup_ftnptr (image, *((guint64*) slot), slot_type);
+                               ((guint64*) slot)++;
+                       }
+               else
+                       g_assert_not_reached();
+
+               vtfixup++;
+       }
+#else
+       g_assert_not_reached();
+#endif
+}
+
static void
free_hash_table (gpointer key, gpointer val, gpointer user_data)
{
@@ -1218,12 +1345,18 @@

        mono_images_unlock ();

+#ifdef PLATFORM_WIN32
+       if (image->is_module_handle)
+               FreeLibrary ((HMODULE) image->raw_data);
+#endif
+
        if (image->raw_buffer_used) {
                if (image->raw_data != NULL)
                        mono_raw_buffer_free (image->raw_data);
        }
        
        if (image->raw_data_allocated) {
+               /* FIXME: do we need this? (image is disposed anyway) */
                /* image->raw_metadata and cli_sections might lie inside 
image->raw_data */
                MonoCLIImageInfo *ii = image->image_info;

@@ -1607,6 +1740,10 @@
                }

                image->files [fileidx - 1] = res;
+#ifdef PLATFORM_WIN32
+               if (res->is_module_handle)
+                       mono_image_fixup_vtable (res);
+#endif
        }
        mono_loader_unlock ();
        g_free (name);
@@ -1658,25 +1795,12 @@
{
        MonoCLIImageInfo *iinfo = image->image_info;
        MonoPEDirEntry *de = &iinfo->cli_cli_header.ch_strong_name;
-       const int top = iinfo->cli_section_count;
-       MonoSectionTable *tables = iinfo->cli_section_tables;
-       int i;
-       guint32 addr = de->rva;
-       
+
        if (size)
                *size = de->size;
        if (!de->size || !de->rva)
                return 0;
-       for (i = 0; i < top; i++){
-               if ((addr >= tables->st_virtual_address) &&
-                   (addr < tables->st_virtual_address + 
tables->st_raw_data_size)){
-                       return tables->st_raw_data_ptr +
-                               (addr - tables->st_virtual_address);
-               }
-               tables++;
-       }
-
-       return 0;
+       return mono_cli_rva_image_map (image, de->rva);
}

/**
Index: mono/mono/metadata/cil-coff.h
===================================================================
--- mono/mono/metadata/cil-coff.h       (revision 101236)
+++ mono/mono/metadata/cil-coff.h       (working copy)
@@ -247,6 +247,17 @@
} MonoDotNetHeader64;

typedef struct {
+       guint32 rva;
+       guint16 count;
+#define VTFIXUP_TYPE_32BIT              0x01
+#define VTFIXUP_TYPE_64BIT              0x02
+#define VTFIXUP_TYPE_FROM_UNMANAGED     0x04
+#define VTFIXUP_TYPE_RETAIN_APPDOMAIN   0x08
+#define VTFIXUP_TYPE_CALL_MOST_DERIVED  0x10
+       guint16 type;
+} MonoVTableFixup;
+
+typedef struct {
        char    st_name [8];
        guint32 st_virtual_size;
        guint32 st_virtual_address;
@@ -311,6 +322,6 @@
        MonoCLIHeader     cli_cli_header;
} MonoCLIImageInfo;

-guint32       mono_cli_rva_image_map (MonoCLIImageInfo *iinfo, guint32 rva);
+guint32       mono_cli_rva_image_map (MonoImage *image, guint32 rva);

#endif /* __MONO_CIL_COFF_H__ */
Index: mono/mono/metadata/image.h
===================================================================
--- mono/mono/metadata/image.h  (revision 101236)
+++ mono/mono/metadata/image.h  (working copy)
@@ -45,6 +45,7 @@
                                         MonoImageOpenStatus *status);
MonoImage    *mono_image_open_from_data_full (char *data, guint32 data_len, 
gboolean need_copy,
                                         MonoImageOpenStatus *status, gboolean 
refonly);
+void          mono_image_fixup_vtable (MonoImage *image);
MonoImage    *mono_image_loaded   (const char *name);
MonoImage    *mono_image_loaded_full   (const char *name, gboolean refonly);
MonoImage    *mono_image_loaded_by_guid (const char *guid);
Index: mono/mono/metadata/coree.c
===================================================================
--- mono/mono/metadata/coree.c  (revision 0)
+++ mono/mono/metadata/coree.c  (revision 0)
@@ -0,0 +1,390 @@
+/*
+ * coree.c: mscoree.dll functions
+ *
+ * Author:
+ *   Kornel Pal <http://www.kornelpal.hu/>
+ *
+ * Copyright (C) 2008 Kornel Pal
+ */
+
+#include <config.h>
+
+#ifdef PLATFORM_WIN32
+
+#include <string.h>
+#include <glib.h>
+#include <mono/io-layer/io-layer.h>
+#include "image.h"
+#include "assembly.h"
+#include "appdomain.h"
+#include "object.h"
+#include "loader.h"
+#include "threads.h"
+#include "environment.h"
+#include "coree.h"
+
+#define STATUS_SUCCESS 0x00000000L
+#define STATUS_INVALID_IMAGE_FORMAT 0xC000007BL
+
+typedef struct _EXPORT_FIXUP
+{
+       LPCSTR Name;
+       DWORD_PTR ProcAddress;
+} EXPORT_FIXUP;
+
+/* called by LdrLoadDll of ntdll.dll after _CorValidateImage */
+BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID 
lpReserved)
+{
+       MonoDomain* domain;
+       gunichar2 filename [MAXPATHLEN];
+       gchar* fname_utf8;
+       gchar* error;
+
+       switch (dwReason)
+       {
+       case DLL_PROCESS_ATTACH:
+               DisableThreadLibraryCalls (hInst);
+               if (mono_get_root_domain ())
+                       return TRUE;
+
+               GetModuleFileName (hInst, filename, MAXPATHLEN);
+               fname_utf8 = g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL);
+               domain = mono_runtime_load (fname_utf8, NULL);
+               error = (gchar*) mono_check_corlib_version ();
+               if (error) {
+                       g_free (error);
+                       g_free (fname_utf8);
+                       mono_runtime_quit ();
+                       return FALSE;
+               }
+
+               mono_assembly_open (fname_utf8, NULL);
+               g_free (fname_utf8);
+               break;
+       }
+
+       return TRUE;
+}
+
+/* called by ntdll.dll reagardless of entry point after _CorValidateImage */
+__int32 STDMETHODCALLTYPE _CorExeMain()
+{
+       MonoDomain* domain;
+       MonoAssembly* assembly;
+       MonoImage* image;
+       MonoMethod* method;
+       guint32 entry;
+       int argc;
+       gunichar2** argvw;
+       gchar** argv;
+       gchar* fname_utf8;
+       gchar* error;
+       int i;
+
+       argvw = CommandLineToArgvW (GetCommandLine (), &argc);
+       g_assert (argc);
+       fname_utf8 = g_utf16_to_utf8 (argvw [0], -1, NULL, NULL, NULL);
+
+       domain = mono_runtime_load (fname_utf8, NULL);
+
+       error = (gchar*) mono_check_corlib_version ();
+       if (error) {
+               g_free (error);
+               MessageBox (NULL, L"Corlib not in sync with this runtime.", 
NULL, MB_ICONERROR);
+               ExitProcess (1);
+       }
+
+       assembly = mono_assembly_open (fname_utf8, NULL);
+       g_assert (assembly);
+       image = mono_assembly_get_image (assembly);
+       entry = mono_image_get_entry_point (image);
+
+       if (!entry) {
+               MessageBox (NULL, L"Assembly doesn't have an entry point.", 
NULL, MB_ICONERROR);
+               ExitProcess (1);
+       }
+
+       method = mono_get_method (image, entry, NULL);
+       if (method == NULL){
+               MessageBox (NULL, L"The entry point method could not be 
loaded.", NULL, MB_ICONERROR);
+               ExitProcess (1);
+       }
+
+       argv = g_new0 (gchar*, argc);
+       argv [0] = fname_utf8;
+       for (i = 1; i < argc; ++i)
+               argv [i] = g_utf16_to_utf8 (argvw [i], -1, NULL, NULL, NULL);
+       LocalFree (argvw);
+
+       mono_runtime_run_main (method, argc, argv, NULL);
+
+       /* return does not terminate the process */
+       ExitProcess (mono_environment_exitcode_get ());
+}
+
+/* called by ntdll.dll before _CorDllMain and _CorExeMain */
+STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
+{
+       IMAGE_DOS_HEADER* DosHeader;
+       IMAGE_NT_HEADERS* NtHeaders;
+       DWORD* Address;
+       DWORD dwOldProtect;
+
+       DosHeader = (IMAGE_DOS_HEADER*)*ImageBase;
+       if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+               return STATUS_INVALID_IMAGE_FORMAT;
+
+       NtHeaders = (IMAGE_NT_HEADERS*)((DWORD_PTR)DosHeader + 
DosHeader->e_lfanew);
+       if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
+               return STATUS_INVALID_IMAGE_FORMAT;
+
+       if (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+               return STATUS_INVALID_IMAGE_FORMAT;
+
+       Address = &NtHeaders->OptionalHeader.AddressOfEntryPoint;
+       if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE, 
&dwOldProtect))
+               return E_UNEXPECTED;
+       if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
+               *Address = (DWORD)((DWORD_PTR)&_CorDllMain - 
(DWORD_PTR)DosHeader);
+       else
+               *Address = (DWORD)((DWORD_PTR)&_CorExeMain - 
(DWORD_PTR)DosHeader);
+       if (!VirtualProtect(Address, sizeof(DWORD), dwOldProtect, 
&dwOldProtect))
+               return E_UNEXPECTED;
+
+       return STATUS_SUCCESS;
+}
+
+/* called by ntdll.dll */
+STDAPI_(VOID) _CorImageUnloading(PVOID ImageBase)
+{
+       /* nothing to do */
+}
+
+/* called by msvcrt.dll when shutting down */
+void STDMETHODCALLTYPE CorExitProcess(int exitCode)
+{
+       if (!mono_runtime_is_shutting_down ()) {
+               mono_runtime_set_shutting_down ();
+               mono_thread_suspend_all_other_threads ();
+               mono_runtime_quit ();
+       }
+       ExitProcess (exitCode);
+}
+
+STDAPI MonoFixupCorEE(HMODULE hModule)
+{
+       /* has to be binary ordered */
+       const EXPORT_FIXUP ExportFixups[] = {
+               {"CorExitProcess", (DWORD_PTR)&CorExitProcess},
+               {"_CorDllMain", (DWORD_PTR)&_CorDllMain},
+               {"_CorExeMain", (DWORD_PTR)&_CorExeMain},
+               {"_CorImageUnloading", (DWORD_PTR)&_CorImageUnloading},
+               {"_CorValidateImage", (DWORD_PTR)&_CorValidateImage},
+               {NULL, 0}
+       };
+
+       IMAGE_DOS_HEADER* DosHeader;
+       IMAGE_NT_HEADERS* NtHeaders;
+       IMAGE_DATA_DIRECTORY* ExportDataDir;
+       IMAGE_EXPORT_DIRECTORY* ExportDir;
+       DWORD* Functions;
+       DWORD* Names;
+       WORD* NameOrdinals;
+       EXPORT_FIXUP* ExportFixup;
+       DWORD* Address;
+       DWORD dwOldProtect;
+       DWORD_PTR ProcAddress;
+       DWORD i;
+
+       DosHeader = (IMAGE_DOS_HEADER*)hModule;
+       if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+               return E_INVALIDARG;
+
+       NtHeaders = (IMAGE_NT_HEADERS*)((DWORD_PTR)DosHeader + 
DosHeader->e_lfanew);
+       if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
+               return E_INVALIDARG;
+
+       if (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+               return E_INVALIDARG;
+
+       if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes <= 
IMAGE_DIRECTORY_ENTRY_EXPORT)
+               return E_FAIL;
+       ExportDataDir = 
&NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
+       if (!ExportDataDir->VirtualAddress || !ExportDataDir->Size)
+               return E_FAIL;
+
+       ExportDir = (IMAGE_EXPORT_DIRECTORY*)((DWORD_PTR)DosHeader + 
ExportDataDir->VirtualAddress);
+       Functions = (DWORD*)((DWORD_PTR)DosHeader + 
ExportDir->AddressOfFunctions);
+       Names = (DWORD*)((DWORD_PTR)DosHeader + ExportDir->AddressOfNames);
+       NameOrdinals = (WORD*)((DWORD_PTR)DosHeader + 
ExportDir->AddressOfNameOrdinals);
+       ExportFixup = (EXPORT_FIXUP*)&ExportFixups;
+
+       for (i = 0; i < ExportDir->NumberOfNames; i++)
+       {
+               int cmp = strcmp((LPCSTR)((DWORD_PTR)DosHeader + Names[i]), 
ExportFixup->Name);
+               if (cmp > 0)
+                       return E_FAIL;
+               if (cmp == 0)
+               {
+                       Address = &Functions[NameOrdinals[i]];
+                       ProcAddress = (DWORD_PTR)DosHeader + *Address;
+                       if (ProcAddress != ExportFixup->ProcAddress) {
+                               if (!VirtualProtect(Address, sizeof(DWORD), 
PAGE_READWRITE, &dwOldProtect))
+                                       return E_UNEXPECTED;
+                               *Address = (DWORD)(ExportFixup->ProcAddress - 
(DWORD_PTR)DosHeader);
+                               if (!VirtualProtect(Address, sizeof(DWORD), 
dwOldProtect, &dwOldProtect))
+                                       return E_UNEXPECTED;
+                       }
+                       ExportFixup++;
+                       if (ExportFixup->Name == NULL)
+                               return NOERROR;
+               }
+       }
+       return E_FAIL;
+}
+
+STDAPI MonoFixupExe(HMODULE hModule)
+{
+       IMAGE_DOS_HEADER* DosHeader;
+       IMAGE_NT_HEADERS* NtHeaders;
+       DWORD_PTR* Address;
+       DWORD dwOldProtect;
+       DWORD_PTR BaseDiff;
+
+       DosHeader = (IMAGE_DOS_HEADER*)hModule;
+       if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+               return E_INVALIDARG;
+
+       NtHeaders = (IMAGE_NT_HEADERS*)((DWORD_PTR)DosHeader + 
DosHeader->e_lfanew);
+       if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
+               return E_INVALIDARG;
+
+       if (NtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+               return E_INVALIDARG;
+
+       if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
+               return NOERROR;
+
+       BaseDiff = (DWORD_PTR)DosHeader - NtHeaders->OptionalHeader.ImageBase;
+       if (BaseDiff != 0)
+       {
+               if (NtHeaders->FileHeader.Characteristics & 
IMAGE_FILE_RELOCS_STRIPPED)
+                       return E_FAIL;
+
+               Address = &NtHeaders->OptionalHeader.ImageBase;
+               if (!VirtualProtect(Address, sizeof(DWORD_PTR), PAGE_READWRITE, 
&dwOldProtect))
+                       return E_UNEXPECTED;
+               *Address = (DWORD_PTR)DosHeader;
+               if (!VirtualProtect(Address, sizeof(DWORD_PTR), dwOldProtect, 
&dwOldProtect))
+                       return E_UNEXPECTED;
+
+               if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes > 
IMAGE_DIRECTORY_ENTRY_BASERELOC)
+               {
+                       IMAGE_DATA_DIRECTORY* BaseRelocDir;
+                       IMAGE_BASE_RELOCATION* BaseReloc;
+                       USHORT* RelocBlock;
+                       ULONG BaseRelocSize;
+                       ULONG RelocBlockSize;
+                       USHORT RelocOffset;
+                       DWORD_PTR UNALIGNED *RelocFixup;
+
+                       BaseRelocDir = 
&NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
+                       if (BaseRelocDir->VirtualAddress && BaseRelocDir->Size)
+                       {
+                               BaseReloc = 
(IMAGE_BASE_RELOCATION*)((DWORD_PTR)DosHeader + BaseRelocDir->VirtualAddress);
+                               BaseRelocSize = BaseRelocDir->Size;
+
+                               while (BaseRelocSize)
+                               {
+                                       RelocBlockSize = BaseReloc->SizeOfBlock;
+
+                                       if (!RelocBlockSize || BaseRelocSize < 
RelocBlockSize)
+                                               return E_FAIL;
+
+                                       BaseRelocSize -= RelocBlockSize;
+                                       RelocBlock = 
(USHORT*)((DWORD_PTR)BaseReloc + IMAGE_SIZEOF_BASE_RELOCATION);
+                                       RelocBlockSize -= 
IMAGE_SIZEOF_BASE_RELOCATION;
+                                       RelocBlockSize /= sizeof(USHORT);
+
+                                       while (RelocBlockSize-- != 0)
+                                       {
+                                               RelocOffset = *RelocBlock & 
(USHORT)0x0fff;
+                                               RelocFixup = 
(DWORD_PTR*)((DWORD_PTR)DosHeader + BaseReloc->VirtualAddress + RelocOffset);
+
+                                               switch (*RelocBlock >> 12)
+                                               {
+                                                       case 
IMAGE_REL_BASED_ABSOLUTE:
+                                                               break;
+
+       #ifdef _WIN64
+                                                       case 
IMAGE_REL_BASED_DIR64:
+       #else
+                                                       case 
IMAGE_REL_BASED_HIGHLOW:
+       #endif
+                                                               if 
(!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), PAGE_EXECUTE_READWRITE, 
&dwOldProtect))
+                                                                       return 
E_UNEXPECTED;
+                                                               *RelocFixup += 
BaseDiff;
+                                                               if 
(!VirtualProtect(RelocFixup, sizeof(DWORD_PTR), dwOldProtect, &dwOldProtect))
+                                                                       return 
E_UNEXPECTED;
+                                                               break;
+
+                                                       default:
+                                                               return E_FAIL;
+                                               }
+
+                                               RelocBlock++;
+                                       }
+                                       BaseReloc = 
(IMAGE_BASE_RELOCATION*)RelocBlock;
+                               }
+                       }
+               }
+       }
+
+       if (NtHeaders->OptionalHeader.NumberOfRvaAndSizes > 
IMAGE_DIRECTORY_ENTRY_IMPORT)
+       {
+               IMAGE_DATA_DIRECTORY* ImportDir;
+               IMAGE_IMPORT_DESCRIPTOR* ImportDesc;
+               HMODULE hImportModule;
+               IMAGE_THUNK_DATA* ImportThunkData;
+               DWORD_PTR ProcAddress;
+
+               ImportDir = 
&NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+               if (ImportDir->VirtualAddress != 0)
+               {
+                       ImportDesc = 
(IMAGE_IMPORT_DESCRIPTOR*)((DWORD_PTR)DosHeader + ImportDir->VirtualAddress);
+                       while (ImportDesc->Name && 
ImportDesc->OriginalFirstThunk)
+                       {
+                               hImportModule = 
LoadLibraryA((PCSTR)((DWORD_PTR)DosHeader + ImportDesc->Name));
+                               if (hImportModule == NULL)
+                                       return E_FAIL;
+
+                               ImportThunkData = 
(IMAGE_THUNK_DATA*)((DWORD_PTR)DosHeader + ImportDesc->OriginalFirstThunk);
+                               while (ImportThunkData->u1.Ordinal != 0)
+                               {
+                                       if 
(IMAGE_SNAP_BY_ORDINAL(ImportThunkData->u1.Ordinal))
+                                               ProcAddress = 
(DWORD_PTR)GetProcAddress(hImportModule, 
(LPCSTR)IMAGE_ORDINAL(ImportThunkData->u1.Ordinal));
+                                       else
+                                       {
+                                               IMAGE_IMPORT_BY_NAME* ImportByName 
= (IMAGE_IMPORT_BY_NAME*)((DWORD_PTR)DosHeader + 
ImportThunkData->u1.AddressOfData);
+                                               ProcAddress = 
(DWORD_PTR)GetProcAddress(hImportModule, ImportByName->Name);
+                                       }
+                                       if (ProcAddress == 0)
+                                               return E_FAIL;
+                                       Address = 
(DWORD_PTR*)((DWORD_PTR)ImportThunkData - ImportDesc->OriginalFirstThunk + 
ImportDesc->FirstThunk);
+                                       if (!VirtualProtect(Address, 
sizeof(DWORD_PTR), PAGE_READWRITE, &dwOldProtect))
+                                               return E_UNEXPECTED;
+                                       *Address = ProcAddress;
+                                       if (!VirtualProtect(Address, 
sizeof(DWORD_PTR), dwOldProtect, &dwOldProtect))
+                                               return E_UNEXPECTED;
+                                       ImportThunkData++;
+                               }
+
+                               ImportDesc++;
+                       }
+               }
+       }
+
+       return NOERROR;
+}
+
+#endif /* PLATFORM_WIN32 */

Property changes on: mono\mono\metadata\coree.c
___________________________________________________________________
Name: svn:eol-style
  + native

Index: mono/mono/metadata/coree.h
===================================================================
--- mono/mono/metadata/coree.h  (revision 0)
+++ mono/mono/metadata/coree.h  (revision 0)
@@ -0,0 +1,20 @@
+/*
+ * coree.h: mscoree.dll functions
+ *
+ * Author:
+ *   Kornel Pal <http://www.kornelpal.hu/>
+ *
+ * Copyright (C) 2008 Kornel Pal
+ */
+
+#ifndef __MONO_COREE_H__
+#define __MONO_COREE_H__
+
+#ifdef PLATFORM_WIN32
+
+STDAPI MonoFixupCorEE(HMODULE hModule);
+STDAPI MonoFixupExe(HMODULE hModule);
+
+#endif /* PLATFORM_WIN32 */
+
+#endif /* __MONO_COREE_H__ */

Property changes on: mono\mono\metadata\coree.h
___________________________________________________________________
Name: svn:eol-style
  + native

Index: mono/mono/metadata/metadata-internals.h
===================================================================
--- mono/mono/metadata/metadata-internals.h     (revision 101236)
+++ mono/mono/metadata/metadata-internals.h     (working copy)
@@ -77,6 +77,11 @@
        guint8 raw_buffer_used    : 1;
        guint8 raw_data_allocated : 1;

+#ifdef PLATFORM_WIN32
+       /* Module was loaded using LoadLibrary */
+       guint8 is_module_handle : 1;
+#endif
+
        /* Whenever this is a dynamically emitted module */
        guint8 dynamic : 1;

Index: mono/mono/metadata/marshal.c
===================================================================
--- mono/mono/metadata/marshal.c        (revision 101236)
+++ mono/mono/metadata/marshal.c        (working copy)
@@ -11,6 +11,7 @@
#include "config.h"
#include "object.h"
#include "loader.h"
+#include "cil-coff.h"
#include "metadata/marshal.h"
#include "metadata/method-builder.h"
#include "metadata/tabledefs.h"
@@ -8471,7 +8472,10 @@

        if (!piinfo->addr) {
                if (pinvoke)
-                       mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
+                       if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE)
+                               exc_arg = "Method contains unsupported native 
code";
+                       else
+                               mono_lookup_pinvoke_call (method, &exc_class, 
&exc_arg);
                else
                        piinfo->addr = mono_lookup_internal_call (method);
        }
@@ -8681,8 +8685,6 @@
                        /* FIXME: need a solution for the moving GC here */
                        mono_mb_emit_ptr (mb, this);
                } else {
-                       /* fixme: */
-                       g_assert_not_reached ();
                }
}
@@ -8789,6 +8791,8 @@

/*
* generates IL code to call managed methods from unmanaged code + * marshaling is based on delegate_klass when specified
+ * this pointer is compiled to the wrapper when specified
 */
MonoMethod *
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass 
*delegate_klass, MonoObject *this)
@@ -8815,7 +8819,10 @@
        if (!this && (res = mono_marshal_find_in_cache (cache, method)))
                return res;

-       invoke = mono_class_get_method_from_name (delegate_klass, "Invoke", 
mono_method_signature (method)->param_count);
+       if (delegate_klass)
+               invoke = mono_class_get_method_from_name (delegate_klass, 
"Invoke", mono_method_signature (method)->param_count);
+       else
+               invoke = method;
        invoke_sig = mono_method_signature (invoke);

        mspecs = g_new0 (MonoMarshalSpec*, mono_method_signature 
(invoke)->param_count + 1);
@@ -8854,7 +8861,7 @@
        /* Why is this a modopt ? */
        if (invoke_sig->ret && invoke_sig->ret->num_mods) {
                for (i = 0; i < invoke_sig->ret->num_mods; ++i) {
-                       MonoClass *cmod_class = mono_class_get 
(delegate_klass->image, invoke_sig->ret->modifiers [i].token);
+                       MonoClass *cmod_class = mono_class_get (delegate_klass ? 
delegate_klass->image : method->klass->image, invoke_sig->ret->modifiers 
[i].token);
                        g_assert (cmod_class);
                        if ((cmod_class->image == mono_defaults.corlib) && !strcmp 
(cmod_class->name_space, "System.Runtime.CompilerServices")) {
                                if (!strcmp (cmod_class->name, "CallConvCdecl"))
@@ -8874,7 +8881,7 @@
                UnmanagedFunctionPointerAttribute = mono_class_from_name (mono_defaults.corlib, 
"System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");

        /* The attribute is only available in Net 2.0 */
-       if (UnmanagedFunctionPointerAttribute) {
+       if (delegate_klass && UnmanagedFunctionPointerAttribute) {
                MonoReflectionUnmanagedFunctionPointerAttribute *attr;
                MonoCustomAttrInfo *cinfo;

@@ -8918,6 +8925,48 @@
        return res;
}

+gpointer
+mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type)
+{
+       MonoMethod *method;
+       MonoMethodSignature *sig;
+       MonoMethodBuilder *mb;
+       int i, param_count;
+       gboolean callvirt;
+
+       method = mono_get_method (image, token, NULL);
+       g_assert (method);
+
+       if (type & VTFIXUP_TYPE_FROM_UNMANAGED) {
+               method = mono_marshal_get_managed_wrapper (method, NULL, NULL);
+               callvirt = FALSE;
+       } else
+               callvirt = (type & VTFIXUP_TYPE_CALL_MOST_DERIVED) && 
(method->flags & METHOD_ATTRIBUTE_VIRTUAL);
+
+       sig = mono_method_signature (method);
+       mb = mono_mb_new (method->klass, method->name, 
MONO_WRAPPER_MANAGED_TO_MANAGED);
+
+       /* FIXME: handle VTFIXUP_TYPE_RETAIN_APPDOMAIN */
+
+       param_count = sig->param_count;
+       if (sig->hasthis)
+               param_count++;
+       for (i = 0; i < param_count; i++)
+               mono_mb_emit_ldarg (mb, i);
+
+       if (callvirt)
+               mono_mb_emit_op (mb, CEE_CALLVIRT, method);
+       else
+               mono_mb_emit_op (mb, CEE_CALL, method);
+       mono_mb_emit_byte (mb, CEE_RET);        
+       
+       mb->dynamic = 1;
+       method = mono_mb_create_method (mb, sig, param_count);
+       mono_mb_free (mb);
+
+       return mono_compile_method (method);
+}
+
static MonoReflectionType *
type_from_handle (MonoType *handle)
{
Index: mono/mono/metadata/marshal.h
===================================================================
--- mono/mono/metadata/marshal.h        (revision 101236)
+++ mono/mono/metadata/marshal.h        (working copy)
@@ -140,6 +140,9 @@
MonoMethod *
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass 
*delegate_klass, MonoObject *this) MONO_INTERNAL;

+gpointer
+mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 
type) MONO_INTERNAL;
+
MonoMethod *
mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, 
gconstpointer func, gboolean check_exceptions) MONO_INTERNAL;

Index: mono/mono/metadata/Makefile.am
===================================================================
--- mono/mono/metadata/Makefile.am      (revision 101236)
+++ mono/mono/metadata/Makefile.am      (working copy)
@@ -108,6 +108,8 @@
        console-io.c            \
        console-io.h    \
        assembly.c      \
+       coree.c \
+       coree.h \
        domain.c        \
        domain-internals.h      \
        opcodes.c       \
Index: mono/mono/mini/mini.c
===================================================================
--- mono/mono/mini/mini.c       (revision 101236)
+++ mono/mono/mini/mini.c       (working copy)
@@ -12321,15 +12321,17 @@
                MonoMethod *nm;
                MonoMethodPInvoke* piinfo = (MonoMethodPInvoke *) method;

-               if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE && 
!MONO_CLASS_IS_IMPORT(method->klass))
-                       g_error ("Method '%s' in assembly '%s' contains native code and mono 
can't run it. The assembly was probably created by Managed C++.\n", mono_method_full_name 
(method, TRUE), method->klass->image->name);
-
                if (!piinfo->addr) {
                        if (method->iflags & 
METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
                                piinfo->addr = mono_lookup_internal_call 
(method);
+                       else if (method->iflags & METHOD_IMPL_ATTRIBUTE_NATIVE)
+#ifdef PLATFORM_WIN32
+                               g_warning ("Method '%s' in assembly '%s' contains native code 
that cannot be executed by Mono in modules loaded from byte arrays. The assembly was probably 
created using C++/CLI.\n", mono_method_full_name (method, TRUE), 
method->klass->image->name);
+#else
+                               g_warning ("Method '%s' in assembly '%s' contains native code 
that cannot be executed by Mono on this platform. The assembly was probably created using 
C++/CLI.\n", mono_method_full_name (method, TRUE), method->klass->image->name);
+#endif
                        else
-                               if (method->flags & 
METHOD_ATTRIBUTE_PINVOKE_IMPL)
-                                       mono_lookup_pinvoke_call (method, NULL, 
NULL);
+                               mono_lookup_pinvoke_call (method, NULL, NULL);
                }
                        nm = mono_marshal_get_native_wrapper (method, 
check_for_pending_exc);
                        return mono_get_addr_from_ftnptr (mono_compile_method 
(nm));
Index: mono/mono/mini/main.c
===================================================================
--- mono/mono/mini/main.c       (revision 101236)
+++ mono/mono/mini/main.c       (working copy)
@@ -1,8 +1,31 @@
#include "mini.h"

+#ifdef PLATFORM_WIN32
+
int
+main ()
+{
+       int argc;
+       gunichar2** argvw;
+       gchar** argv;
+       int i;
+
+       argvw = CommandLineToArgvW (GetCommandLine (), &argc);
+       argv = g_new0 (gchar*, argc);
+       for (i = 0; i < argc; i++)
+               argv [i] = g_utf16_to_utf8 (argvw [i], -1, NULL, NULL, NULL);
+
+       LocalFree (argvw);
+
+       return mono_main (argc, argv);
+}
+
+#else
+
+int
main (int argc, char* argv[])
{
        return mono_main (argc, argv);
}

+#endif
Index: mono/mono/mini/Makefile.am
===================================================================
--- mono/mono/mini/Makefile.am  (revision 101236)
+++ mono/mono/mini/Makefile.am  (working copy)
@@ -58,7 +58,7 @@
endif

if PLATFORM_WIN32
-libmono_la_LDFLAGS=-no-undefined -avoid-version $(monoldflags)
+libmono_la_LDFLAGS=-no-undefined -avoid-version -Wl,--kill-at $(monoldflags)
else
libmono_la_LDFLAGS=$(monoldflags)
endif
Index: mono/mono/mini/driver.c
===================================================================
--- mono/mono/mini/driver.c     (revision 101236)
+++ mono/mono/mini/driver.c     (working copy)
@@ -45,6 +45,7 @@
#include <mono/metadata/security-core-clr.h>
#include <mono/metadata/gc-internal.h>
#include "mono/utils/mono-counters.h"
+#include <mono/os/gc_wrapper.h>

#include "mini.h"
#include "jit.h"
@@ -1006,6 +1007,25 @@
#define error_if_aot_unsupported()
#endif

+#ifdef PLATFORM_WIN32
+extern HMODULE mono_module_handle;
+
+BOOL APIENTRY DllMain (HMODULE module_handle, DWORD reason, LPVOID reserved)
+{
+       if (!GC_DllMain (module_handle, reason, reserved))
+               return FALSE;
+
+       switch (reason)
+       {
+       case DLL_PROCESS_ATTACH:
+               mono_module_handle = module_handle;
+               mono_install_runtime_load (mini_init);
+               break;
+       }
+       return TRUE;
+}
+#endif
+
int
mono_main (int argc, char* argv[])
{
Index: mono/msvc/create-windef.pl
===================================================================
--- mono/msvc/create-windef.pl  (revision 101236)
+++ mono/msvc/create-windef.pl  (working copy)
@@ -19,6 +19,7 @@
        push @symbols, $1;
}
close (SYMS);
+push @symbols, "MonoFixupCorEE";
@symbols = sort @symbols;

open (OUT, ">$outfile") || die "Cannot open '$outfile': $!\n";
Index: mono/msvc/libmono.vcproj
===================================================================
--- mono/msvc/libmono.vcproj    (revision 101236)
+++ mono/msvc/libmono.vcproj    (working copy)
@@ -2287,6 +2287,14 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\mono\metadata\coree.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\mono\metadata\coree.h"
+                               >
+                       </File>
+                       <File
                                
RelativePath="..\mono\metadata\culture-info-tables.h"
                                >
                        </File>
Index: mono/msvc/mono.def
===================================================================
--- mono/msvc/mono.def  (revision 101236)
+++ mono/msvc/mono.def  (working copy)
@@ -1,6 +1,7 @@
; file generated by create-windef.pl
LIBRARY mono.dll
EXPORTS
+MonoFixupCorEE
mono_add_internal_call
mono_alloc_special_static_data
mono_array_class_get

Property changes on: mono\msvc\mono.def
___________________________________________________________________
Name: svn:eol-style
  + native

#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0501
#define UNICODE
#define _UNICODE
#include <windows.h>

#define STATUS_SUCCESS 0x00000000L
#define STATUS_INVALID_IMAGE_FORMAT 0xC000007BL

typedef HRESULT (STDAPICALLTYPE *MONOFIXUPCOREE)(HMODULE);

static HMODULE g_hMono;

STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName);
STDAPI stub_CorValidateImage(PVOID *ImageBase, LPCWSTR FileName);
static PVOID g_CorValidateImage = stub_CorValidateImage;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
        MONOFIXUPCOREE MonoFixupCorEE;
        PVOID new_CorValidateImage;

        switch (dwReason)
        {
        case DLL_PROCESS_ATTACH:
                DisableThreadLibraryCalls(hModule);
                g_hMono = LoadLibrary(L"C:\\Program 
Files\\Mono\\bin\\mono.dll");
                if (g_hMono == NULL)
                        return FALSE;
                MonoFixupCorEE = (MONOFIXUPCOREE)GetProcAddress(g_hMono, 
"MonoFixupCorEE");
                if (MonoFixupCorEE == NULL || 
!SUCCEEDED(MonoFixupCorEE(hModule)))
                        return FALSE;
                /* GetProcAddress on _CorValidateImage is called by ntdll.dll 
before DllMain in processes created from managed executables */
                new_CorValidateImage = GetProcAddress(hModule, 
"_CorValidateImage");
                if (new_CorValidateImage != &_CorValidateImage)
                        g_CorValidateImage = new_CorValidateImage;
                break;
        case DLL_PROCESS_DETACH:
                if (g_hMono != NULL)
                        FreeLibrary(g_hMono);
                break;
        }
        return TRUE;
}

BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID 
lpReserved)
{
        switch (dwReason)
        {
        case DLL_PROCESS_ATTACH:
                DisableThreadLibraryCalls(hInst);
                break;
        }
        return TRUE;
}

__int32 STDMETHODCALLTYPE _CorExeMain()
{
        return 0;
}

STDAPI stub_CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
{
        return STATUS_SUCCESS;
}

__declspec(naked) STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
{
        __asm jmp g_CorValidateImage;
}

STDAPI_(VOID) _CorImageUnloading(PVOID ImageBase)
{
}

void STDMETHODCALLTYPE CorExitProcess(int exitCode)
{
        ExitProcess(exitCode);
}
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to