From 50f4edae54b1bc0d40f39fa833c78f3033e12dbc Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 11 Dec 2006 22:13:48 +0100 Subject: [PATCH] mscoree: Take advantage of an installed Mono for Windows to run .NET applications. --- dlls/mscoree/Makefile.in | 2 +- dlls/mscoree/mscoree_main.c | 92 ++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/dlls/mscoree/Makefile.in b/dlls/mscoree/Makefile.in index 76dc4989596..77ae5d23c1d 100644 --- a/dlls/mscoree/Makefile.in +++ b/dlls/mscoree/Makefile.in @@ -3,7 +3,7 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = mscoree.dll -IMPORTS = kernel32 +IMPORTS = advapi32 kernel32 C_SRCS = \ mscoree_main.c diff --git a/dlls/mscoree/mscoree_main.c b/dlls/mscoree/mscoree_main.c index 8caf2fbf25a..69416126de3 100644 --- a/dlls/mscoree/mscoree_main.c +++ b/dlls/mscoree/mscoree_main.c @@ -24,6 +24,7 @@ #include "windef.h" #include "winbase.h" #include "winuser.h" +#include "winreg.h" #include "ole2.h" #include "wine/debug.h" @@ -74,10 +75,97 @@ BOOL WINAPI _CorDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } +static LPWSTR get_mono_exe() +{ + static const WCHAR mono_exe[] = {'b','i','n','\\','m','o','n','o','.','e','x','e',' ',0}; + static const WCHAR mono_key[] = {'S','o','f','t','w','a','r','e','\\','N','o','v','e','l','l','\\','M','o','n','o',0}; + static const WCHAR defaul_clr[] = {'D','e','f','a','u','l','t','C','L','R',0}; + static const WCHAR install_root[] = {'S','d','k','I','n','s','t','a','l','l','R','o','o','t',0}; + static const WCHAR slash[] = {'\\',0}; + + WCHAR version[64], version_key[MAX_PATH], root[MAX_PATH], *ret; + DWORD len, size; + HKEY key; + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, mono_key, 0, KEY_READ, &key)) + return NULL; + + len = sizeof(version); + if (RegQueryValueExW(key, defaul_clr, 0, NULL, (LPBYTE)version, &len)) + { + RegCloseKey(key); + return NULL; + } + RegCloseKey(key); + + lstrcpyW(version_key, mono_key); + lstrcatW(version_key, slash); + lstrcatW(version_key, version); + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, version_key, 0, KEY_READ, &key)) + return NULL; + + len = sizeof(root); + if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)root, &len)) + { + RegCloseKey(key); + return NULL; + } + RegCloseKey(key); + + size = len + sizeof(slash) + sizeof(mono_exe); + if (!(ret = HeapAlloc(GetProcessHeap(), 0, size))) return NULL; + + lstrcpyW(ret, root); + lstrcatW(ret, slash); + lstrcatW(ret, mono_exe); + + return ret; +} + int WINAPI _CorExeMain(void) { - FIXME("Directly running .NET applications not supported.\n"); - return -1; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + WCHAR *mono_exe, *cmd_line; + DWORD size, exit_code; + + if (!(mono_exe = get_mono_exe())) + { + MESSAGE("install the Windows version of Mono to run .NET executables\n"); + return -1; + } + + size = (lstrlenW(mono_exe) + lstrlenW(GetCommandLineW()) + 1) * sizeof(WCHAR); + if (!(cmd_line = HeapAlloc(GetProcessHeap(), 0, size))) + { + HeapFree(GetProcessHeap(), 0, mono_exe); + return -1; + } + + lstrcpyW(cmd_line, mono_exe); + HeapFree(GetProcessHeap(), 0, mono_exe); + lstrcatW(cmd_line, GetCommandLineW()); + + TRACE("new command line: %s\n", debugstr_w(cmd_line)); + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + if (!CreateProcessW(NULL, cmd_line, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) + { + HeapFree(GetProcessHeap(), 0, cmd_line); + return -1; + } + HeapFree(GetProcessHeap(), 0, cmd_line); + + /* wait for the process to exit */ + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess(pi.hProcess, &exit_code); + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + return (int)exit_code; } int WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPCWSTR imageName, LPCWSTR loaderName, LPCWSTR cmdLine)