2 * Implementation of mscoree.dll
3 * Microsoft Component Object Runtime Execution Engine
5 * Copyright 2006 Paul Chitescu
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/unicode.h"
36 #include "mscoree_private.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL( mscoree
);
42 static BOOL
get_mono_path(LPWSTR path
)
44 static const WCHAR mono_key
[] = {'S','o','f','t','w','a','r','e','\\','N','o','v','e','l','l','\\','M','o','n','o',0};
45 static const WCHAR defaul_clr
[] = {'D','e','f','a','u','l','t','C','L','R',0};
46 static const WCHAR install_root
[] = {'S','d','k','I','n','s','t','a','l','l','R','o','o','t',0};
47 static const WCHAR slash
[] = {'\\',0};
49 WCHAR version
[64], version_key
[MAX_PATH
];
53 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, mono_key
, 0, KEY_READ
, &key
))
56 len
= sizeof(version
);
57 if (RegQueryValueExW(key
, defaul_clr
, 0, NULL
, (LPBYTE
)version
, &len
))
64 lstrcpyW(version_key
, mono_key
);
65 lstrcatW(version_key
, slash
);
66 lstrcatW(version_key
, version
);
68 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, version_key
, 0, KEY_READ
, &key
))
71 len
= sizeof(WCHAR
) * MAX_PATH
;
72 if (RegQueryValueExW(key
, install_root
, 0, NULL
, (LPBYTE
)path
, &len
))
82 static CRITICAL_SECTION mono_lib_cs
;
83 static CRITICAL_SECTION_DEBUG mono_lib_cs_debug
=
86 { &mono_lib_cs_debug
.ProcessLocksList
,
87 &mono_lib_cs_debug
.ProcessLocksList
},
88 0, 0, { (DWORD_PTR
)(__FILE__
": mono_lib_cs") }
90 static CRITICAL_SECTION mono_lib_cs
= { &mono_lib_cs_debug
, -1, 0, 0, 0, 0 };
94 void (*mono_config_parse
)(const char *filename
);
95 MonoAssembly
* (*mono_domain_assembly_open
) (MonoDomain
*domain
, const char *name
);
96 void (*mono_jit_cleanup
)(MonoDomain
*domain
);
97 int (*mono_jit_exec
)(MonoDomain
*domain
, MonoAssembly
*assembly
, int argc
, char *argv
[]);
98 MonoDomain
* (*mono_jit_init
)(const char *file
);
99 int (*mono_jit_set_trace_options
)(const char* options
);
100 void (*mono_set_dirs
)(const char *assembly_dir
, const char *config_dir
);
102 static void set_environment(LPCWSTR bin_path
)
104 WCHAR path_env
[MAX_PATH
];
107 static const WCHAR pathW
[] = {'P','A','T','H',0};
109 /* We have to modify PATH as Mono loads other DLLs from this directory. */
110 GetEnvironmentVariableW(pathW
, path_env
, sizeof(path_env
)/sizeof(WCHAR
));
111 len
= strlenW(path_env
);
112 path_env
[len
++] = ';';
113 strcpyW(path_env
+len
, bin_path
);
114 SetEnvironmentVariableW(pathW
, path_env
);
117 static HMODULE
load_mono(void)
119 static const WCHAR mono_dll
[] = {'\\','b','i','n','\\','m','o','n','o','.','d','l','l',0};
120 static const WCHAR libmono_dll
[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','.','d','l','l',0};
121 static const WCHAR bin
[] = {'\\','b','i','n',0};
122 static const WCHAR lib
[] = {'\\','l','i','b',0};
123 static const WCHAR etc
[] = {'\\','e','t','c',0};
125 WCHAR mono_path
[MAX_PATH
], mono_dll_path
[MAX_PATH
+16], mono_bin_path
[MAX_PATH
+4];
126 WCHAR mono_lib_path
[MAX_PATH
+4], mono_etc_path
[MAX_PATH
+4];
127 char mono_lib_path_a
[MAX_PATH
], mono_etc_path_a
[MAX_PATH
];
129 EnterCriticalSection(&mono_lib_cs
);
133 if (!get_mono_path(mono_path
)) goto end
;
135 strcpyW(mono_bin_path
, mono_path
);
136 strcatW(mono_bin_path
, bin
);
137 set_environment(mono_bin_path
);
139 strcpyW(mono_lib_path
, mono_path
);
140 strcatW(mono_lib_path
, lib
);
141 WideCharToMultiByte(CP_UTF8
, 0, mono_lib_path
, -1, mono_lib_path_a
, MAX_PATH
, NULL
, NULL
);
143 strcpyW(mono_etc_path
, mono_path
);
144 strcatW(mono_etc_path
, etc
);
145 WideCharToMultiByte(CP_UTF8
, 0, mono_etc_path
, -1, mono_etc_path_a
, MAX_PATH
, NULL
, NULL
);
147 strcpyW(mono_dll_path
, mono_path
);
148 strcatW(mono_dll_path
, mono_dll
);
149 mono_handle
= LoadLibraryW(mono_dll_path
);
153 strcpyW(mono_dll_path
, mono_path
);
154 strcatW(mono_dll_path
, libmono_dll
);
155 mono_handle
= LoadLibraryW(mono_dll_path
);
158 if (!mono_handle
) goto end
;
160 #define LOAD_MONO_FUNCTION(x) do { \
161 x = (void*)GetProcAddress(mono_handle, #x); \
163 mono_handle = NULL; \
168 LOAD_MONO_FUNCTION(mono_config_parse
);
169 LOAD_MONO_FUNCTION(mono_domain_assembly_open
);
170 LOAD_MONO_FUNCTION(mono_jit_cleanup
);
171 LOAD_MONO_FUNCTION(mono_jit_exec
);
172 LOAD_MONO_FUNCTION(mono_jit_init
);
173 LOAD_MONO_FUNCTION(mono_jit_set_trace_options
);
174 LOAD_MONO_FUNCTION(mono_set_dirs
);
176 #undef LOAD_MONO_FUNCTION
178 mono_set_dirs(mono_lib_path_a
, mono_etc_path_a
);
180 mono_config_parse(NULL
);
184 result
= mono_handle
;
186 LeaveCriticalSection(&mono_lib_cs
);
189 MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n");
194 HRESULT WINAPI
CorBindToRuntimeHost(LPCWSTR pwszVersion
, LPCWSTR pwszBuildFlavor
,
195 LPCWSTR pwszHostConfigFile
, VOID
*pReserved
,
196 DWORD startupFlags
, REFCLSID rclsid
,
197 REFIID riid
, LPVOID
*ppv
)
199 FIXME("(%s, %s, %s, %p, %d, %s, %s, %p): semi-stub!\n", debugstr_w(pwszVersion
),
200 debugstr_w(pwszBuildFlavor
), debugstr_w(pwszHostConfigFile
), pReserved
,
201 startupFlags
, debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
203 if (!get_mono_path(NULL
))
205 MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n");
212 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
214 TRACE("(%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
218 case DLL_WINE_PREATTACH
:
219 return FALSE
; /* prefer native version */
220 case DLL_PROCESS_ATTACH
:
221 DisableThreadLibraryCalls(hinstDLL
);
223 case DLL_PROCESS_DETACH
:
229 BOOL WINAPI
_CorDllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
231 FIXME("(%p, %d, %p): stub\n", hinstDLL
, fdwReason
, lpvReserved
);
235 case DLL_PROCESS_ATTACH
:
236 DisableThreadLibraryCalls(hinstDLL
);
238 case DLL_PROCESS_DETACH
:
244 static void get_utf8_args(int *argc
, char ***argv
)
250 argvw
= CommandLineToArgvW(GetCommandLineW(), argc
);
252 for (i
=0; i
<*argc
; i
++)
254 size
+= sizeof(char*);
255 size
+= WideCharToMultiByte(CP_UTF8
, 0, argvw
[i
], -1, NULL
, 0, NULL
, NULL
);
257 size
+= sizeof(char*);
259 *argv
= HeapAlloc(GetProcessHeap(), 0, size
);
260 current_arg
= (char*)(*argv
+ *argc
+ 1);
262 for (i
=0; i
<*argc
; i
++)
264 (*argv
)[i
] = current_arg
;
265 current_arg
+= WideCharToMultiByte(CP_UTF8
, 0, argvw
[i
], -1, current_arg
, size
, NULL
, NULL
);
268 (*argv
)[*argc
] = NULL
;
270 HeapFree(GetProcessHeap(), 0, argvw
);
273 __int32 WINAPI
_CorExeMain(void)
277 char trace_setting
[256];
281 MonoAssembly
*assembly
;
282 char filename
[MAX_PATH
];
289 get_utf8_args(&argc
, &argv
);
291 trace_size
= GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting
, sizeof(trace_setting
));
295 mono_jit_set_trace_options(trace_setting
);
298 GetModuleFileNameA(NULL
, filename
, MAX_PATH
);
300 domain
= mono_jit_init(filename
);
302 assembly
= mono_domain_assembly_open(domain
, filename
);
304 exit_code
= mono_jit_exec(domain
, assembly
, argc
, argv
);
306 mono_jit_cleanup(domain
);
308 HeapFree(GetProcessHeap(), 0, argv
);
313 __int32 WINAPI
_CorExeMain2(PBYTE ptrMemory
, DWORD cntMemory
, LPWSTR imageName
, LPWSTR loaderName
, LPWSTR cmdLine
)
315 TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory
, cntMemory
, debugstr_w(imageName
), debugstr_w(loaderName
), debugstr_w(cmdLine
));
316 FIXME("Directly running .NET applications not supported.\n");
320 void WINAPI
CorExitProcess(int exitCode
)
322 FIXME("(%x) stub\n", exitCode
);
323 ExitProcess(exitCode
);
326 VOID WINAPI
_CorImageUnloading(PVOID imageBase
)
328 TRACE("(%p): stub\n", imageBase
);
331 HRESULT WINAPI
_CorValidateImage(PVOID
* imageBase
, LPCWSTR imageName
)
333 TRACE("(%p, %s): stub\n", imageBase
, debugstr_w(imageName
));
337 HRESULT WINAPI
GetCORSystemDirectory(LPWSTR pbuffer
, DWORD cchBuffer
, DWORD
*dwLength
)
339 FIXME("(%p, %d, %p): stub!\n", pbuffer
, cchBuffer
, dwLength
);
349 HRESULT WINAPI
GetCORVersion(LPWSTR pbuffer
, DWORD cchBuffer
, DWORD
*dwLength
)
351 static const WCHAR version
[] = {'v','1','.','1','.','4','3','2','2',0};
353 FIXME("(%p, %d, %p): semi-stub!\n", pbuffer
, cchBuffer
, dwLength
);
358 *dwLength
= lstrlenW(version
);
360 if (cchBuffer
< *dwLength
)
361 return ERROR_INSUFFICIENT_BUFFER
;
364 lstrcpyW(pbuffer
, version
);
369 HRESULT WINAPI
GetRequestedRuntimeInfo(LPCWSTR pExe
, LPCWSTR pwszVersion
, LPCWSTR pConfigurationFile
,
370 DWORD startupFlags
, DWORD runtimeInfoFlags
, LPWSTR pDirectory
, DWORD dwDirectory
, DWORD
*dwDirectoryLength
,
371 LPWSTR pVersion
, DWORD cchBuffer
, DWORD
*dwlength
)
373 FIXME("(%s, %s, %s, 0x%08x, 0x%08x, %p, 0x%08x, %p, %p, 0x%08x, %p) stub\n", debugstr_w(pExe
),
374 debugstr_w(pwszVersion
), debugstr_w(pConfigurationFile
), startupFlags
, runtimeInfoFlags
, pDirectory
,
375 dwDirectory
, dwDirectoryLength
, pVersion
, cchBuffer
, dwlength
);
376 return GetCORVersion(pVersion
, cchBuffer
, dwlength
);
379 HRESULT WINAPI
LoadLibraryShim( LPCWSTR szDllName
, LPCWSTR szVersion
, LPVOID pvReserved
, HMODULE
* phModDll
)
381 FIXME("(%p %s, %p, %p, %p): semi-stub\n", szDllName
, debugstr_w(szDllName
), szVersion
, pvReserved
, phModDll
);
383 if (phModDll
) *phModDll
= LoadLibraryW(szDllName
);
387 HRESULT WINAPI
LockClrVersion(FLockClrVersionCallback hostCallback
, FLockClrVersionCallback
*pBeginHostSetup
, FLockClrVersionCallback
*pEndHostSetup
)
389 FIXME("(%p %p %p): stub\n", hostCallback
, pBeginHostSetup
, pEndHostSetup
);
393 HRESULT WINAPI
CoInitializeCor(DWORD fFlags
)
395 FIXME("(0x%08x): stub\n", fFlags
);
399 HRESULT WINAPI
GetAssemblyMDImport(LPCWSTR szFileName
, REFIID riid
, IUnknown
**ppIUnk
)
401 FIXME("(%p %s, %s, %p): stub\n", szFileName
, debugstr_w(szFileName
), debugstr_guid(riid
), *ppIUnk
);
402 return ERROR_CALL_NOT_IMPLEMENTED
;
405 HRESULT WINAPI
GetVersionFromProcess(HANDLE hProcess
, LPWSTR pVersion
, DWORD cchBuffer
, DWORD
*dwLength
)
407 FIXME("(%p, %p, %d, %p): stub\n", hProcess
, pVersion
, cchBuffer
, dwLength
);
411 HRESULT WINAPI
LoadStringRCEx(LCID culture
, UINT resId
, LPWSTR pBuffer
, int iBufLen
, int bQuiet
, int* pBufLen
)
414 if ((iBufLen
<= 0) || !pBuffer
)
418 FIXME("(%d, %x, %p, %d, %d, %p): semi-stub\n", culture
, resId
, pBuffer
, iBufLen
, bQuiet
, pBufLen
);
424 *pBufLen
= lstrlenW(pBuffer
);
428 HRESULT WINAPI
LoadStringRC(UINT resId
, LPWSTR pBuffer
, int iBufLen
, int bQuiet
)
430 return LoadStringRCEx(-1, resId
, pBuffer
, iBufLen
, bQuiet
, NULL
);
433 HRESULT WINAPI
CorBindToRuntimeEx(LPWSTR szVersion
, LPWSTR szBuildFlavor
, DWORD nflags
, REFCLSID rslsid
,
434 REFIID riid
, LPVOID
*ppv
)
436 FIXME("%s %s %d %s %s %p\n", debugstr_w(szVersion
), debugstr_w(szBuildFlavor
), nflags
, debugstr_guid( rslsid
),
437 debugstr_guid( riid
), ppv
);
439 if(IsEqualGUID( riid
, &IID_ICorRuntimeHost
))
441 *ppv
= create_corruntimehost();
448 HRESULT WINAPI
CorBindToCurrentRuntime(LPCWSTR filename
, REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
450 FIXME("(%s, %s, %s, %p): stub\n", debugstr_w(filename
), debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
454 STDAPI
ClrCreateManagedInstance(LPCWSTR pTypeName
, REFIID riid
, void **ppObject
)
456 FIXME("(%s,%s,%p)\n", debugstr_w(pTypeName
), debugstr_guid(riid
), ppObject
);
460 BOOL WINAPI
StrongNameSignatureVerification(LPCWSTR filename
, DWORD inFlags
, DWORD
* pOutFlags
)
462 FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename
), inFlags
, pOutFlags
);
466 BOOL WINAPI
StrongNameSignatureVerificationEx(LPCWSTR filename
, BOOL forceVerification
, BOOL
* pVerified
)
468 FIXME("(%s, %u, %p): stub\n", debugstr_w(filename
), forceVerification
, pVerified
);
472 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
* ppv
)
474 FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
481 HRESULT WINAPI
DllRegisterServer(void)
487 HRESULT WINAPI
DllUnregisterServer(void)
493 HRESULT WINAPI
DllCanUnloadNow(VOID
)
498 INT WINAPI
ND_RU1( const void *ptr
, INT offset
)
500 return *((const BYTE
*)ptr
+ offset
);
503 INT WINAPI
ND_RI2( const void *ptr
, INT offset
)
505 return *(const SHORT
*)((const BYTE
*)ptr
+ offset
);
508 INT WINAPI
ND_RI4( const void *ptr
, INT offset
)
510 return *(const INT
*)((const BYTE
*)ptr
+ offset
);
513 INT64 WINAPI
ND_RI8( const void *ptr
, INT offset
)
515 return *(const INT64
*)((const BYTE
*)ptr
+ offset
);
518 void WINAPI
ND_WU1( void *ptr
, INT offset
, BYTE val
)
520 *((BYTE
*)ptr
+ offset
) = val
;
523 void WINAPI
ND_WI2( void *ptr
, INT offset
, SHORT val
)
525 *(SHORT
*)((BYTE
*)ptr
+ offset
) = val
;
528 void WINAPI
ND_WI4( void *ptr
, INT offset
, INT val
)
530 *(INT
*)((BYTE
*)ptr
+ offset
) = val
;
533 void WINAPI
ND_WI8( void *ptr
, INT offset
, INT64 val
)
535 *(INT64
*)((BYTE
*)ptr
+ offset
) = val
;
538 void WINAPI
ND_CopyObjDst( const void *src
, void *dst
, INT offset
, INT size
)
540 memcpy( (BYTE
*)dst
+ offset
, src
, size
);
543 void WINAPI
ND_CopyObjSrc( const void *src
, INT offset
, void *dst
, INT size
)
545 memcpy( dst
, (const BYTE
*)src
+ offset
, size
);