mscoree: Invoke installed win32 mono runtime for .NET executables (try 5)

Paul Chitescu paulc at voip.null.ro
Wed Oct 11 09:31:15 CDT 2006


Changelog: mscoree: Invoke installed win32 mono runtime for .NET executables 
with capability to run native runtime or other wrapper.

The controlling Registry key used and default value are:

[HKCU\Software\Wine\mscoree]
"Runtimes"="MONOEMBED"

Creating the key and setting the "Runtimes" value to an empty string will 
disable this feature and render .NET executables unrunable.

The code is inspired by the one in winebrowser.

Several alternatives can be provided in Registry, separated by commas. For 
each an attempt to execute it (spawnvp with OVERLAY flag set) is made. The 
exception is the keyword MONOEMBED that will try to locate and dynamically 
load an installed Win32 mono.

Examples:
"Runtimes"="MONOEMBED,/usr/bin/mono,mono"
"Runtimes"="mono"
"Runtimes"="mono,MONOEMBED"

By default only MONOEMBED is enabled as it seems to provide best compatibility 
and integration with Wine. It requires a proper installation of mono Win32 and 
finds its location from Registry.

This is the 5th version of the patch.

Paul
-------------- next part --------------
--- ./dlls/mscoree/Makefile.in.orig	2006-10-06 21:38:15.000000000 +0300
+++ ./dlls/mscoree/Makefile.in	2006-10-09 21:41:26.000000000 +0300
@@ -3,10 +3,11 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = mscoree.dll
-IMPORTS   = kernel32
+IMPORTS   = kernel32 advapi32
 
 C_SRCS = \
-	mscoree_main.c
+	mscoree_main.c \
+	mscoree_mono.c
 
 @MAKE_DLL_RULES@
 
--- ./dlls/mscoree/mscoree_main.c.orig	2006-10-06 21:38:15.000000000 +0300
+++ ./dlls/mscoree/mscoree_main.c	2006-10-11 17:20:28.000000000 +0300
@@ -19,15 +19,93 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include <stdarg.h>
+#include "config.h"
+#include "wine/port.h"
+#include "wine/library.h"
+#include "wine/debug.h"
 
 #include "windef.h"
 #include "winbase.h"
+#include "winreg.h"
 
-#include "wine/debug.h"
+#include <stdarg.h>
+#include <errno.h>
+
+#include "mscoree_priv.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
 
+/* By default only try win32 embedded mono */
+static const char defaultRuntimes[] = "MONOEMBED";
+
+static int runMain()
+{
+    char runtimes[256];
+    char* item;
+    int argc, rval, i;
+    const char* *argv;
+    DWORD length;
+    HKEY key = 0;
+
+    /* this code is adapted from winebrowser */
+    length = sizeof(runtimes);
+    /* @@ Wine registry key: HKCU\Software\Wine\mscoree */
+    if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\mscoree", 0, KEY_READ, &key) != ERROR_SUCCESS)
+	strcpy(runtimes,defaultRuntimes);
+    else
+    {
+	DWORD type = 0;
+	if (RegQueryValueExA(key, "Runtimes", 0, &type, (LPBYTE)runtimes, &length) != ERROR_SUCCESS)
+	    strcpy(runtimes,defaultRuntimes);
+	RegCloseKey(key);
+    }
+    if (!runtimes[0])
+    {
+	WARN("Runtimes are disabled from Registry.\n");
+	return ENOSYS;
+    }
+    /* allocate an array with space for one extra argument */
+    argc = __wine_main_argc+1;
+    argv = (const char**)HeapAlloc(GetProcessHeap(), 0, (argc+1)*sizeof(char*));
+    if (!argv)
+    {
+	ERR("Could not allocate memory!\n");
+	return ENOMEM;
+    }
+    for (i = 0; i < argc; i++)
+	argv[i+1] = __wine_main_argv[i];
+    argv[argc] = NULL;
+    rval = -1;
+    for (item = strtok(runtimes, ","); item; item = strtok(NULL, ","))
+    {
+	if (!item[0])
+	    continue;
+	TRACE("Attempting to use: %s\n", debugstr_a(item));
+	argv[0] = NULL;
+	if (strcmp(item, "MONOEMBED") == 0)
+	{
+	    /* try to call win32 mono runtime */
+	    rval = MONO_CorExeMain(argc, argv);
+	    if (rval >= 0)
+		break;
+	}
+	else
+	{
+	    argv[0] = item;
+	    spawnvp(_P_OVERLAY, item, argv);
+	    /* if we reach this point exec() failed */
+	    rval = -1;
+	}
+    }
+    HeapFree(GetProcessHeap(), 0, argv);
+    if (rval < 0)
+    {
+	ERR("No suitable runtime could be started.\n");
+	rval = ENOSYS;
+    }
+    return rval;
+}
+
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
     TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
@@ -62,14 +140,13 @@
 
 int WINAPI _CorExeMain(void)
 {
-    FIXME("Directly running .NET applications not supported.\n");
-    return -1;
+    TRACE("\n");
+    return runMain();
 }
 
 int WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPCWSTR imageName, LPCWSTR loaderName, LPCWSTR cmdLine)
 {
-    TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine));
-    FIXME("Directly running .NET applications not supported.\n");
+    FIXME("(%p, %u, %s, %s, %s): stub\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine));
     return -1;
 }
 
--- ./programs/regedit/regproc.c.orig	2006-08-01 19:41:14.000000000 +0300
+++ ./programs/regedit/regproc.c	2006-10-11 04:58:54.000000000 +0300
@@ -881,6 +881,8 @@
 {
     LPSTR line           = NULL;  /* line read from input stream */
     ULONG lineSize       = REG_VAL_BUF_SIZE;
+    int encoding         = -1;    /* guessed file encoding */
+    int offset           =  0;    /* offset for encoding magic */
 
     line = HeapAlloc(GetProcessHeap(), 0, lineSize);
     CHECK_ENOUGH_MEMORY(line);
@@ -929,6 +931,48 @@
                 }
             }
 
+            /* Attempt to guess the encoding from the first several bytes */
+            if (encoding < 0) {
+                if (line [0] == '\377' && line [1] == '\376') {
+                    encoding = 2; /* FF FE    => UCS-2 little endian */
+                    offset = 2;
+                }
+                else if (line [0] == '\357' && line [1] == '\277' && line [2] == '\275') {
+                    encoding = 1; /* EF BF BD => UTF-8 */
+                    offset = 3;
+                    if (line [3] == '\357' && line [4] == '\277' && line [5] == '\275')
+                        offset += 3;
+                }
+                else
+                    encoding = 0; /* default  => ASCII (hope so...) */
+                if (encoding) {
+                    fprintf(stderr,"%s: WARNING - %s encoding (detected %d magic bytes).\n",
+                            getAppName(),((encoding == 1) ? "UTF-8" : "UCS-2"),offset);
+                }
+            }
+
+            /* Extremely crude routine to convert to 8-bit */
+            if (encoding) {
+                int i = 0;
+                char c;
+                if (encoding > 1) {
+                    /* FIXME: this is ugly */
+                    if (! (offset || *s))
+                        offset = encoding-1;
+                    /* FIXME: we should convert */
+                    while ((c = s [(encoding*i)+offset]) != 0)
+                        s [i++] = c;
+                }
+                else if (offset) {
+                    /* just skip over the magic */
+                    while ((c = s [i+offset]) != 0)
+                        s [i++] = c;
+                }
+		s [i] = '\0';
+                fprintf(stderr,"converted: '%s' (%p)\n", s, s);
+                offset = 0;
+            }
+
             /* If we didn't read the eol nor the eof go around for the rest */
             s_eol = strchr (s, '\n');
             if (!feof (in) && !s_eol) {
@@ -968,7 +1012,8 @@
             break; /* That is the full virtual line */
         }
 
-        command(line);
+                fprintf(stderr,"process: '%s'\n", line);
+//        command(line);
     }
     command(NULL);
 


More information about the wine-patches mailing list