ReactOS 0.4.16-dev-2357-g35d0dfe
metahost.c
Go to the documentation of this file.
1/*
2 * ICLRMetaHost - discovery and management of available .NET runtimes
3 *
4 * Copyright 2010 Vincent Povirk for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdio.h>
22#include <stdarg.h>
23#include <assert.h>
24
25#define COBJMACROS
26
27#include "windef.h"
28#include "winbase.h"
29#include "winreg.h"
30#include "winternl.h"
31#include "ole2.h"
32#include "shlwapi.h"
33
34#include "corerror.h"
35#include "cor.h"
36#include "mscoree.h"
37#include "corhdr.h"
38#include "cordebug.h"
39#include "metahost.h"
40#include "fusion.h"
41#include "wine/list.h"
42#include "mscoree_private.h"
43
44#include "wine/debug.h"
45
47
48static const struct ICLRRuntimeInfoVtbl CLRRuntimeInfoVtbl;
49
50#define NUM_RUNTIMES 4
51
53 {{&CLRRuntimeInfoVtbl}, 1, 0, 3705, 0},
54 {{&CLRRuntimeInfoVtbl}, 1, 1, 4322, 0},
55 {{&CLRRuntimeInfoVtbl}, 2, 0, 50727, 0},
56 {{&CLRRuntimeInfoVtbl}, 4, 0, 30319, 0}
57};
58
61{
62 0, 0, &runtime_list_cs,
65 0, 0, { (DWORD_PTR)(__FILE__ ": runtime_list_cs") }
66};
67static CRITICAL_SECTION runtime_list_cs = { &runtime_list_cs_debug, -1, 0, 0, 0, 0 };
68
70{
72
74};
75
77
79
82
83typedef struct _MonoProfilerDesc *MonoProfilerHandle;
84
86
91WORD (CDECL *mono_assembly_name_get_version)(MonoAssemblyName *aname, WORD *minor, WORD *build, WORD *revision);
93void (CDECL *mono_callspec_set_assembly)(MonoAssembly *assembly);
96MonoMethod* (CDECL *mono_class_get_method_from_name)(MonoClass *klass, const char *name, int param_count);
97static void (CDECL *mono_config_parse)(const char *filename);
100BOOL (CDECL *mono_domain_set)(MonoDomain *domain,BOOL force);
101void (CDECL *mono_domain_set_config)(MonoDomain *domain,const char *base_dir,const char *config_file_name);
102static void (CDECL *mono_free)(void *);
106static void (CDECL *mono_install_assembly_preload_hook)(MonoAssemblyPreLoadFunc func, void *user_data);
107int (CDECL *mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
108MonoDomain* (CDECL *mono_jit_init_version)(const char *domain_name, const char *runtime_version);
109static void (CDECL *mono_jit_set_aot_mode)(MonoAotMode mode);
110static int (CDECL *mono_jit_set_trace_options)(const char* options);
116static MonoProfilerHandle (CDECL *mono_profiler_create)(MonoProfiler *prof);
117static void (CDECL *mono_profiler_install)(MonoProfiler *prof, MonoProfileFunc shutdown_callback);
118static void (CDECL *mono_profiler_set_runtime_shutdown_begin_callback)(MonoProfilerHandle handle, MonoProfilerRuntimeShutdownBeginCallback cb);
121void (CDECL *mono_runtime_object_init)(MonoObject *this_obj);
122void (CDECL *mono_runtime_quit)(void);
123static void (CDECL *mono_set_crash_chaining)(BOOL chain_signals);
124static void (CDECL *mono_set_dirs)(const char *assembly_dir, const char *config_dir);
125static void (CDECL *mono_set_verbose_level)(DWORD level);
129void (CDECL *mono_thread_manage)(void);
130void (CDECL *mono_trace_set_print_handler)(MonoPrintCallback callback);
131void (CDECL *mono_trace_set_printerr_handler)(MonoPrintCallback callback);
132void (CDECL *mono_trace_set_log_handler)(MonoLogCallback callback, void *user_data);
134static void (CDECL *wine_mono_install_assembly_preload_hook)(WineMonoAssemblyPreLoadFunc func, void *user_data);
135static void (CDECL *wine_mono_install_assembly_preload_hook_v2)(WineMonoAssemblyPreLoadFunc func, void *user_data);
136
137static BOOL find_mono_dll(LPCWSTR path, LPWSTR dll_path);
138
139static MonoAssembly* CDECL mono_assembly_preload_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data);
140static MonoAssembly* CDECL wine_mono_assembly_preload_hook_fn(MonoAssemblyName *aname, char **assemblies_path, int *search_path, void *user_data);
141static MonoAssembly* CDECL wine_mono_assembly_preload_hook_v2_fn(MonoAssemblyName *aname, char **assemblies_path, int *flags, void *user_data);
142
144
146 char* fname, UINT has_entry_point, MonoImageOpenStatus* status)
147{
148 return mono_image_open(fname, status);
149}
150
151static void CDECL set_crash_chaining_dummy(BOOL crash_chaining)
152{
153}
154
156{
157}
158
160{
161}
162
163static HRESULT load_mono(LPCWSTR mono_path)
164{
165 static const WCHAR lib[] = {'\\','l','i','b',0};
166 static const WCHAR etc[] = {'\\','e','t','c',0};
167 WCHAR mono_dll_path[MAX_PATH+16];
168 WCHAR mono_lib_path[MAX_PATH+4], mono_etc_path[MAX_PATH+4];
169 char mono_lib_path_a[MAX_PATH], mono_etc_path_a[MAX_PATH];
170 int aot_size;
171 char aot_setting[256];
172 int trace_size;
173 char trace_setting[256];
174 int verbose_size;
175 char verbose_setting[256];
176
178 {
179 ERR("Cannot load Mono after it has been shut down.\n");
180 return E_FAIL;
181 }
182
183 if (!mono_handle)
184 {
185 lstrcpyW(mono_lib_path, mono_path);
186 lstrcatW(mono_lib_path, lib);
187 WideCharToMultiByte(CP_UTF8, 0, mono_lib_path, -1, mono_lib_path_a, MAX_PATH, NULL, NULL);
188
189 lstrcpyW(mono_etc_path, mono_path);
190 lstrcatW(mono_etc_path, etc);
191 WideCharToMultiByte(CP_UTF8, 0, mono_etc_path, -1, mono_etc_path_a, MAX_PATH, NULL, NULL);
192
193 if (!find_mono_dll(mono_path, mono_dll_path)) goto fail;
194
195 mono_handle = LoadLibraryW(mono_dll_path);
196
197 if (!mono_handle) goto fail;
198
199#define LOAD_MONO_FUNCTION(x) do { \
200 x = (void*)GetProcAddress(mono_handle, #x); \
201 if (!x) { \
202 goto fail; \
203 } \
204} while (0);
205
210 LOAD_MONO_FUNCTION(mono_assembly_name_get_version);
212 LOAD_MONO_FUNCTION(mono_config_parse);
218 LOAD_MONO_FUNCTION(mono_domain_set);
219 LOAD_MONO_FUNCTION(mono_domain_set_config);
220 LOAD_MONO_FUNCTION(mono_free);
223 LOAD_MONO_FUNCTION(mono_install_assembly_preload_hook);
224 LOAD_MONO_FUNCTION(mono_jit_exec);
226 LOAD_MONO_FUNCTION(mono_jit_set_trace_options);
234 LOAD_MONO_FUNCTION(mono_runtime_object_init);
235 LOAD_MONO_FUNCTION(mono_runtime_quit);
236 LOAD_MONO_FUNCTION(mono_set_dirs);
237 LOAD_MONO_FUNCTION(mono_set_verbose_level);
241 LOAD_MONO_FUNCTION(mono_thread_manage);
242
243#undef LOAD_MONO_FUNCTION
244
245#define LOAD_OPT_MONO_FUNCTION(x, default) do { \
246 x = (void*)GetProcAddress(mono_handle, #x); \
247 if (!x) { \
248 x = default; \
249 } \
250} while (0);
251
252 LOAD_OPT_MONO_FUNCTION(mono_callspec_set_assembly, NULL);
254 LOAD_OPT_MONO_FUNCTION(mono_jit_set_aot_mode, NULL);
255 LOAD_OPT_MONO_FUNCTION(mono_profiler_create, NULL);
256 LOAD_OPT_MONO_FUNCTION(mono_profiler_install, NULL);
257 LOAD_OPT_MONO_FUNCTION(mono_profiler_set_runtime_shutdown_begin_callback, NULL);
258 LOAD_OPT_MONO_FUNCTION(mono_set_crash_chaining, set_crash_chaining_dummy);
259 LOAD_OPT_MONO_FUNCTION(mono_trace_set_print_handler, set_print_handler_dummy);
260 LOAD_OPT_MONO_FUNCTION(mono_trace_set_printerr_handler, set_print_handler_dummy);
261 LOAD_OPT_MONO_FUNCTION(mono_trace_set_log_handler, set_log_handler_dummy);
263 LOAD_OPT_MONO_FUNCTION(wine_mono_install_assembly_preload_hook, NULL);
264 LOAD_OPT_MONO_FUNCTION(wine_mono_install_assembly_preload_hook_v2, NULL);
265
266#undef LOAD_OPT_MONO_FUNCTION
267
268 if (mono_callspec_set_assembly == NULL)
269 {
270 mono_callspec_set_assembly = (void*)GetProcAddress(mono_handle, "mono_trace_set_assembly");
271 if (!mono_callspec_set_assembly) goto fail;
272 }
273
274 if (mono_profiler_create != NULL)
275 {
276 /* Profiler API v2 */
277 MonoProfilerHandle handle = mono_profiler_create(NULL);
278 mono_profiler_set_runtime_shutdown_begin_callback(handle, mono_shutdown_callback_fn);
279 }
280 else if (mono_profiler_install != NULL)
281 {
282 /* Profiler API v1 */
283 mono_profiler_install(NULL, mono_shutdown_callback_fn);
284 }
285
286 mono_set_crash_chaining(TRUE);
287
288 mono_trace_set_print_handler(mono_print_handler_fn);
289 mono_trace_set_printerr_handler(mono_print_handler_fn);
290 mono_trace_set_log_handler(mono_log_handler_fn, NULL);
291
292 mono_set_dirs(mono_lib_path_a, mono_etc_path_a);
293
294 mono_config_parse(NULL);
295
296 if (wine_mono_install_assembly_preload_hook_v2)
297 wine_mono_install_assembly_preload_hook_v2(wine_mono_assembly_preload_hook_v2_fn, NULL);
298 else if (wine_mono_install_assembly_preload_hook)
299 wine_mono_install_assembly_preload_hook(wine_mono_assembly_preload_hook_fn, NULL);
300 else
301 mono_install_assembly_preload_hook(mono_assembly_preload_hook_fn, NULL);
302
303 aot_size = GetEnvironmentVariableA("WINE_MONO_AOT", aot_setting, sizeof(aot_setting));
304
305 if (aot_size)
306 {
308 if (strcmp(aot_setting, "interp") == 0)
310 else if (strcmp(aot_setting, "none") == 0)
312 else
313 {
314 ERR("unknown WINE_MONO_AOT setting, valid settings are interp and none\n");
316 }
317 if (mono_jit_set_aot_mode != NULL)
318 {
319 mono_jit_set_aot_mode(mode);
320 }
321 else
322 {
323 ERR("mono_jit_set_aot_mode export not found\n");
324 }
325 }
326
327 trace_size = GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting, sizeof(trace_setting));
328
329 if (trace_size)
330 {
331 mono_jit_set_trace_options(trace_setting);
332 }
333
334 verbose_size = GetEnvironmentVariableA("WINE_MONO_VERBOSE", verbose_setting, sizeof(verbose_setting));
335
336 if (verbose_size)
337 {
338 mono_set_verbose_level(verbose_setting[0] - '0');
339 }
340 }
341
342 return S_OK;
343
344fail:
345 ERR("Could not load Mono into this process\n");
348 return E_FAIL;
349}
350
351static char* get_exe_basename_utf8(void)
352{
353 WCHAR filenameW[MAX_PATH], *basenameW;
354
356
357 basenameW = wcsrchr(filenameW, '\\');
358 if (basenameW)
359 basenameW += 1;
360 else
361 basenameW = filenameW;
362
363 return WtoA(basenameW);
364}
365
367{
368 static MonoDomain* root_domain;
369
370 if (root_domain != NULL)
371 return root_domain;
372
374
375 if (root_domain == NULL)
376 {
377 char *exe_basename;
378
379 exe_basename = get_exe_basename_utf8();
380
381 root_domain = mono_jit_init_version(exe_basename, "v4.0.30319");
382
383 free(exe_basename);
384
386 }
387
389
390 return root_domain;
391}
392
394{
396}
397
399{
400 WARN("stub\n");
401 return S_OK;
402}
403
405{
406 WARN("stub\n");
407 return S_OK;
408}
409
411{
412 HRESULT hr = S_OK;
413 WCHAR mono_path[MAX_PATH];
414
415 if (This->loaded_runtime)
416 {
417 *result = This->loaded_runtime;
418 return hr;
419 }
420
421 if (!get_mono_path(mono_path, FALSE))
422 {
423 ERR("Wine Mono is not installed\n");
424 return CLR_E_SHIM_RUNTIME;
425 }
426
428
429 if (This->loaded_runtime)
430 {
431 *result = This->loaded_runtime;
433 return hr;
434 }
435
436 if (GlobalCLRMetaHost.callback)
437 {
438 GlobalCLRMetaHost.callback(&This->ICLRRuntimeInfo_iface, thread_set_fn, thread_unset_fn);
439 }
440
441 hr = load_mono(mono_path);
442
443 if (SUCCEEDED(hr))
444 hr = RuntimeHost_Construct(This, &This->loaded_runtime);
445
447
448 if (SUCCEEDED(hr))
449 *result = This->loaded_runtime;
450
451 return hr;
452}
453
455{
457 {
458 ERR("Process exited with a Mono runtime loaded.\n");
459 return;
460 }
461}
462
463static inline CLRRuntimeInfo *impl_from_ICLRRuntimeInfo(ICLRRuntimeInfo *iface)
464{
465 return CONTAINING_RECORD(iface, CLRRuntimeInfo, ICLRRuntimeInfo_iface);
466}
467
468static HRESULT WINAPI CLRRuntimeInfo_QueryInterface(ICLRRuntimeInfo* iface,
469 REFIID riid,
470 void **ppvObject)
471{
472 TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
473
474 if ( IsEqualGUID( riid, &IID_ICLRRuntimeInfo ) ||
476 {
477 *ppvObject = iface;
478 }
479 else
480 {
481 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
482 return E_NOINTERFACE;
483 }
484
485 ICLRRuntimeInfo_AddRef( iface );
486
487 return S_OK;
488}
489
490static ULONG WINAPI CLRRuntimeInfo_AddRef(ICLRRuntimeInfo* iface)
491{
492 return 2;
493}
494
495static ULONG WINAPI CLRRuntimeInfo_Release(ICLRRuntimeInfo* iface)
496{
497 return 1;
498}
499
500static HRESULT WINAPI CLRRuntimeInfo_GetVersionString(ICLRRuntimeInfo* iface,
501 LPWSTR pwzBuffer, DWORD *pcchBuffer)
502{
504 DWORD buffer_size = *pcchBuffer;
505 HRESULT hr = S_OK;
506 char version[11];
507 DWORD size;
508
509 TRACE("%p %p %p\n", iface, pwzBuffer, pcchBuffer);
510
511 size = snprintf(version, sizeof(version), "v%lu.%lu.%lu", This->major, This->minor, This->build);
512
513 assert(size <= sizeof(version));
514
515 *pcchBuffer = MultiByteToWideChar(CP_UTF8, 0, version, -1, NULL, 0);
516
517 if (pwzBuffer)
518 {
519 if (buffer_size >= *pcchBuffer)
520 MultiByteToWideChar(CP_UTF8, 0, version, -1, pwzBuffer, buffer_size);
521 else
523 }
524
525 return hr;
526}
527
528static BOOL get_install_root(LPWSTR install_dir)
529{
530 static const WCHAR dotnet_key[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','.','N','E','T','F','r','a','m','e','w','o','r','k','\\',0};
531 static const WCHAR install_root[] = {'I','n','s','t','a','l','l','R','o','o','t',0};
532
533 DWORD len;
534 HKEY key;
535
536 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, dotnet_key, 0, KEY_READ, &key))
537 return FALSE;
538
539 len = MAX_PATH * sizeof(WCHAR);
540 if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)install_dir, &len))
541 {
543 return FALSE;
544 }
546
547 return TRUE;
548}
549
551 LPWSTR pwzBuffer, DWORD *pcchBuffer)
552{
553 static const WCHAR slash[] = {'\\',0};
554 DWORD buffer_size = *pcchBuffer;
557 DWORD version_size, size;
558 HRESULT hr = S_OK;
559
560 TRACE("%p %p %p\n", iface, pwzBuffer, pcchBuffer);
561
563 {
564 ERR("error reading registry key for installroot\n");
565 return E_FAIL;
566 }
567 else
568 {
569 version_size = MAX_PATH;
570 ICLRRuntimeInfo_GetVersionString(iface, version, &version_size);
572 lstrcatW(system_dir, slash);
573 size = lstrlenW(system_dir) + 1;
574 }
575
576 *pcchBuffer = size;
577
578 if (pwzBuffer)
579 {
580 if (buffer_size >= size)
581 lstrcpyW(pwzBuffer, system_dir);
582 else
584 }
585
586 return hr;
587}
588
589static HRESULT WINAPI CLRRuntimeInfo_IsLoaded(ICLRRuntimeInfo* iface,
590 HANDLE hndProcess, BOOL *pbLoaded)
591{
592 FIXME("%p %p %p\n", iface, hndProcess, pbLoaded);
593
594 return E_NOTIMPL;
595}
596
597static HRESULT WINAPI CLRRuntimeInfo_LoadErrorString(ICLRRuntimeInfo* iface,
598 UINT iResourceID, LPWSTR pwzBuffer, DWORD *pcchBuffer, LONG iLocaleid)
599{
600 FIXME("%p %u %p %p %lx\n", iface, iResourceID, pwzBuffer, pcchBuffer, iLocaleid);
601
602 return E_NOTIMPL;
603}
604
605static HRESULT WINAPI CLRRuntimeInfo_LoadLibrary(ICLRRuntimeInfo* iface,
606 LPCWSTR pwzDllName, HMODULE *phndModule)
607{
609 HRESULT hr;
611
612 TRACE("%p %s %p\n", iface, debugstr_w(pwzDllName), phndModule);
613
615 hr = ICLRRuntimeInfo_GetVersionString(iface, version, &cchBuffer);
616 if (FAILED(hr)) return hr;
617
618 return LoadLibraryShim(pwzDllName, version, NULL, phndModule);
619}
620
621static HRESULT WINAPI CLRRuntimeInfo_GetProcAddress(ICLRRuntimeInfo* iface,
622 LPCSTR pszProcName, LPVOID *ppProc)
623{
624 FIXME("%p %s %p\n", iface, debugstr_a(pszProcName), ppProc);
625
626 return E_NOTIMPL;
627}
628
629static HRESULT WINAPI CLRRuntimeInfo_GetInterface(ICLRRuntimeInfo* iface,
630 REFCLSID rclsid, REFIID riid, LPVOID *ppUnk)
631{
634 HRESULT hr;
635
636 TRACE("%p %s %s %p\n", iface, debugstr_guid(rclsid), debugstr_guid(riid), ppUnk);
637
639
640 if (SUCCEEDED(hr))
641 hr = RuntimeHost_GetInterface(host, rclsid, riid, ppUnk);
642
643 return hr;
644}
645
646static HRESULT WINAPI CLRRuntimeInfo_IsLoadable(ICLRRuntimeInfo* iface,
647 BOOL *pbLoadable)
648{
649 FIXME("%p %p\n", iface, pbLoadable);
650
651 return E_NOTIMPL;
652}
653
655 DWORD dwStartupFlags, LPCWSTR pwzHostConfigFile)
656{
657 FIXME("%p %lx %s\n", iface, dwStartupFlags, debugstr_w(pwzHostConfigFile));
658
659 return E_NOTIMPL;
660}
661
663 DWORD *pdwStartupFlags, LPWSTR pwzHostConfigFile, DWORD *pcchHostConfigFile)
664{
665 FIXME("%p %p %p %p\n", iface, pdwStartupFlags, pwzHostConfigFile, pcchHostConfigFile);
666
667 return E_NOTIMPL;
668}
669
671{
672 FIXME("%p\n", iface);
673
674 return E_NOTIMPL;
675}
676
677static HRESULT WINAPI CLRRuntimeInfo_IsStarted(ICLRRuntimeInfo* iface,
678 BOOL *pbStarted, DWORD *pdwStartupFlags)
679{
680 FIXME("%p %p %p\n", iface, pbStarted, pdwStartupFlags);
681
682 return E_NOTIMPL;
683}
684
685static const struct ICLRRuntimeInfoVtbl CLRRuntimeInfoVtbl = {
701};
702
704{
706
707 assert(This->ICLRRuntimeInfo_iface.lpVtbl == &CLRRuntimeInfoVtbl);
708
710}
711
712#ifdef __i386__
713static const WCHAR libmono2_arch_dll[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','-','2','.','0','-','x','8','6','.','d','l','l',0};
714#elif defined(__x86_64__)
715static const WCHAR libmono2_arch_dll[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','-','2','.','0','-','x','8','6','_','6','4','.','d','l','l',0};
716#else
717static const WCHAR libmono2_arch_dll[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','-','2','.','0','.','d','l','l',0};
718#endif
719
721{
722 static const WCHAR mono2_dll[] = {'\\','b','i','n','\\','m','o','n','o','-','2','.','0','.','d','l','l',0};
723 static const WCHAR libmono2_dll[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','-','2','.','0','.','d','l','l',0};
725
726 lstrcpyW(dll_path, path);
727 lstrcatW(dll_path, libmono2_arch_dll);
728 attributes = GetFileAttributesW(dll_path);
729
730 if (attributes == INVALID_FILE_ATTRIBUTES)
731 {
732 lstrcpyW(dll_path, path);
733 lstrcatW(dll_path, mono2_dll);
734 attributes = GetFileAttributesW(dll_path);
735 }
736
737 if (attributes == INVALID_FILE_ATTRIBUTES)
738 {
739 lstrcpyW(dll_path, path);
740 lstrcatW(dll_path, libmono2_dll);
741 attributes = GetFileAttributesW(dll_path);
742 }
743
744 return (attributes != INVALID_FILE_ATTRIBUTES);
745}
746
748{
749 static const WCHAR subdir_mono[] = {'\\','m','o','n','o','\\','m','o','n','o','-','2','.','0', 0};
750 WCHAR base_path[MAX_PATH], mono_dll_path[MAX_PATH];
751
752 /* c:\windows\mono\mono-2.0 */
753 GetWindowsDirectoryW(base_path, MAX_PATH);
754 lstrcatW(base_path, subdir_mono);
755
756 if (find_mono_dll(base_path, mono_dll_path))
757 {
758 lstrcpyW(path, base_path);
759 return TRUE;
760 }
761
762 return FALSE;
763}
764
766{
767 static const WCHAR keyname[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','M','o','n','o',0};
768 static const WCHAR valuename[] = {'R','u','n','t','i','m','e','P','a','t','h',0};
769 WCHAR base_path[MAX_PATH], mono_dll_path[MAX_PATH];
770 HKEY hkey;
771 DWORD res, valuesize;
772 BOOL ret=FALSE;
773
774 /* @@ Wine registry key: HKCU\Software\Wine\Mono */
775 res = RegOpenKeyW(HKEY_CURRENT_USER, keyname, &hkey);
776 if (res != ERROR_SUCCESS)
777 return FALSE;
778
779 valuesize = sizeof(base_path);
780 res = RegGetValueW(hkey, NULL, valuename, RRF_RT_REG_SZ, NULL, base_path, &valuesize);
781 if (res == ERROR_SUCCESS && find_mono_dll(base_path, mono_dll_path))
782 {
783 lstrcpyW(path, base_path);
784 ret = TRUE;
785 }
786
787 RegCloseKey(hkey);
788
789 return ret;
790}
791
793{
794 static const WCHAR unix_prefix[] = {'\\','\\','?','\\','u','n','i','x','\\'};
795 static const WCHAR basedir[] = L"\\wine-mono-" WINE_MONO_VERSION;
796 LPWSTR dos_dir;
797 WCHAR mono_dll_path[MAX_PATH];
798 DWORD len;
799 BOOL ret;
800
801 if (memcmp(dir, unix_prefix, sizeof(unix_prefix)) == 0)
802 return FALSE; /* No drive letter for this directory */
803
804 len = lstrlenW( dir ) + lstrlenW( basedir ) + 1;
805 if (!(dos_dir = malloc( len * sizeof(WCHAR) ))) return FALSE;
806 lstrcpyW( dos_dir, dir );
807 lstrcatW( dos_dir, basedir );
808
809 ret = find_mono_dll(dos_dir, mono_dll_path);
810 if (ret)
811 lstrcpyW(path, dos_dir);
812
813 free(dos_dir);
814
815 return ret;
816}
817
818#ifndef __REACTOS__
819static BOOL get_mono_path_unix(const char *unix_dir, LPWSTR path)
820{
821 static WCHAR * (CDECL *p_wine_get_dos_file_name)(const char*);
822 LPWSTR dos_dir;
823 BOOL ret;
824
825 if (!p_wine_get_dos_file_name)
826 {
827 p_wine_get_dos_file_name = (void*)GetProcAddress(GetModuleHandleA("kernel32"), "wine_get_dos_file_name");
828 if (!p_wine_get_dos_file_name)
829 return FALSE;
830 }
831
832 dos_dir = p_wine_get_dos_file_name(unix_dir);
833 if (!dos_dir)
834 return FALSE;
835
836 ret = get_mono_path_dos( dos_dir, path);
837
838 HeapFree(GetProcessHeap(), 0, dos_dir);
839 return ret;
840}
841#endif
842
844{
845 static const WCHAR winedatadirW[] = {'W','I','N','E','D','A','T','A','D','I','R',0};
846 static const WCHAR winebuilddirW[] = {'W','I','N','E','B','U','I','L','D','D','I','R',0};
847 static const WCHAR unix_prefix[] = {'\\','?','?','\\','u','n','i','x','\\'};
848 static const WCHAR monoW[] = {'\\','m','o','n','o',0};
849 static const WCHAR dotdotmonoW[] = {'\\','.','.','\\','m','o','n','o',0};
850 const WCHAR *data_dir, *suffix;
851 WCHAR *package_dir;
852 BOOL ret;
853
854 if ((data_dir = _wgetenv( winedatadirW )))
855 suffix = monoW;
856 else if ((data_dir = _wgetenv( winebuilddirW )))
857 suffix = dotdotmonoW;
858 else
859 return FALSE;
860
861 if (!wcsncmp( data_dir, unix_prefix, wcslen(unix_prefix) )) return FALSE;
862 data_dir += 4; /* skip \??\ prefix */
863 package_dir = malloc((wcslen(data_dir) + wcslen(suffix) + 1) * sizeof(WCHAR));
864 lstrcpyW( package_dir, data_dir );
865 lstrcatW( package_dir, suffix );
866
867 ret = get_mono_path_dos(package_dir, path);
868
869 free(package_dir);
870
871 return ret;
872}
873
875{
876#ifdef __REACTOS__
877 return (!skip_local && get_mono_path_local(path)) ||
880#else
881 return (!skip_local && get_mono_path_local(path)) ||
884 get_mono_path_unix(INSTALL_DATADIR "/wine/mono", path) ||
885 (strcmp(INSTALL_DATADIR, "/usr/share") &&
886 get_mono_path_unix("/usr/share/wine/mono", path)) ||
887 get_mono_path_unix("/opt/wine/mono", path);
888#endif
889}
890
892{
896};
897
898static const struct IEnumUnknownVtbl InstalledRuntimeEnum_Vtbl;
899
901{
903}
904
906 void **ppvObject)
907{
908 TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
909
912 {
913 *ppvObject = iface;
914 }
915 else
916 {
917 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
918 return E_NOINTERFACE;
919 }
920
921 IEnumUnknown_AddRef( iface );
922
923 return S_OK;
924}
925
927{
930
931 TRACE("(%p) refcount=%lu\n", iface, ref);
932
933 return ref;
934}
935
937{
940
941 TRACE("(%p) refcount=%lu\n", iface, ref);
942
943 if (ref == 0)
944 {
945 free(This);
946 }
947
948 return ref;
949}
950
952 IUnknown **rgelt, ULONG *pceltFetched)
953{
955 ULONG num_fetched = 0;
957 IUnknown *item;
958
959 TRACE("(%p,%lu,%p,%p)\n", iface, celt, rgelt, pceltFetched);
960
961 while (num_fetched < celt)
962 {
963 if (This->pos >= NUM_RUNTIMES)
964 {
965 hr = S_FALSE;
966 break;
967 }
968 item = (IUnknown*)&runtimes[This->pos].ICLRRuntimeInfo_iface;
969 IUnknown_AddRef(item);
970 rgelt[num_fetched] = item;
971 num_fetched++;
972 This->pos++;
973 }
974
975 if (pceltFetched)
976 *pceltFetched = num_fetched;
977
978 return hr;
979}
980
982{
984 ULONG num_fetched = 0;
986
987 TRACE("(%p,%lu)\n", iface, celt);
988
989 while (num_fetched < celt)
990 {
991 if (This->pos >= NUM_RUNTIMES)
992 {
993 hr = S_FALSE;
994 break;
995 }
996 num_fetched++;
997 This->pos++;
998 }
999
1000 return hr;
1001}
1002
1004{
1006
1007 TRACE("(%p)\n", iface);
1008
1009 This->pos = 0;
1010
1011 return S_OK;
1012}
1013
1015{
1017 struct InstalledRuntimeEnum *new_enum;
1018
1019 TRACE("(%p)\n", iface);
1020
1021 new_enum = malloc(sizeof(*new_enum));
1022 if (!new_enum)
1023 return E_OUTOFMEMORY;
1024
1026 new_enum->ref = 1;
1027 new_enum->pos = This->pos;
1028
1029 *ppenum = &new_enum->IEnumUnknown_iface;
1030
1031 return S_OK;
1032}
1033
1034static const struct IEnumUnknownVtbl InstalledRuntimeEnum_Vtbl = {
1042};
1043
1045 REFIID riid,
1046 void **ppvObject)
1047{
1048 TRACE("%s %p\n", debugstr_guid(riid), ppvObject);
1049
1050 if ( IsEqualGUID( riid, &IID_ICLRMetaHost ) ||
1052 {
1053 *ppvObject = iface;
1054 }
1055 else
1056 {
1057 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
1058 return E_NOINTERFACE;
1059 }
1060
1061 ICLRMetaHost_AddRef( iface );
1062
1063 return S_OK;
1064}
1065
1067{
1068 return 2;
1069}
1070
1072{
1073 return 1;
1074}
1075
1076static inline BOOL isDigit(WCHAR c)
1077{
1078 return c >= '0' && c <= '9';
1079}
1080
1082{
1083 *major = 0;
1084 *minor = 0;
1085 *build = 0;
1086
1087 if (version[0] == 'v' || version[0] == 'V')
1088 {
1089 version++;
1090 if (!isDigit(*version))
1091 return FALSE;
1092
1093 while (isDigit(*version))
1094 *major = *major * 10 + (*version++ - '0');
1095
1096 if (*version == 0)
1097 return TRUE;
1098
1099 if (*version++ != '.' || !isDigit(*version))
1100 return FALSE;
1101
1102 while (isDigit(*version))
1103 *minor = *minor * 10 + (*version++ - '0');
1104
1105 if (*version == 0)
1106 return TRUE;
1107
1108 if (*version++ != '.' || !isDigit(*version))
1109 return FALSE;
1110
1111 while (isDigit(*version))
1112 *build = *build * 10 + (*version++ - '0');
1113
1114 return *version == 0;
1115 }
1116 else
1117 return FALSE;
1118}
1119
1120static HRESULT get_runtime(LPCWSTR pwzVersion, BOOL allow_short,
1121 REFIID iid, LPVOID *ppRuntime)
1122{
1123 int i;
1125
1126 if (!pwzVersion)
1127 return E_POINTER;
1128
1129 if (!parse_runtime_version(pwzVersion, &major, &minor, &build))
1130 {
1131 ERR("Cannot parse %s\n", debugstr_w(pwzVersion));
1132 return CLR_E_SHIM_RUNTIME;
1133 }
1134
1135 for (i=0; i<NUM_RUNTIMES; i++)
1136 {
1137 if (runtimes[i].major == major && runtimes[i].minor == minor &&
1138 (runtimes[i].build == build || (allow_short && major >= 4 && build == 0)))
1139 {
1140 return ICLRRuntimeInfo_QueryInterface(&runtimes[i].ICLRRuntimeInfo_iface, iid,
1141 ppRuntime);
1142 }
1143 }
1144
1145 FIXME("Unrecognized version %s\n", debugstr_w(pwzVersion));
1146 return CLR_E_SHIM_RUNTIME;
1147}
1148
1150 LPCWSTR pwzVersion, REFIID iid, LPVOID *ppRuntime)
1151{
1152 TRACE("%s %s %p\n", debugstr_w(pwzVersion), debugstr_guid(iid), ppRuntime);
1153
1154 return get_runtime(pwzVersion, FALSE, iid, ppRuntime);
1155}
1156
1158 LPCWSTR pwzFilePath, LPWSTR pwzBuffer, DWORD *pcchBuffer)
1159{
1161 HRESULT hr;
1162 LPSTR version;
1163 ULONG buffer_size=*pcchBuffer;
1164
1165 TRACE("%s %p %p\n", debugstr_w(pwzFilePath), pwzBuffer, pcchBuffer);
1166
1167 hr = assembly_create(&assembly, pwzFilePath);
1168
1169 if (SUCCEEDED(hr))
1170 {
1172
1173 if (SUCCEEDED(hr))
1174 {
1175 *pcchBuffer = MultiByteToWideChar(CP_UTF8, 0, version, -1, NULL, 0);
1176
1177 if (pwzBuffer)
1178 {
1179 if (buffer_size >= *pcchBuffer)
1180 MultiByteToWideChar(CP_UTF8, 0, version, -1, pwzBuffer, buffer_size);
1181 else
1183 }
1184 }
1185
1187 }
1188
1189 return hr;
1190}
1191
1193 IEnumUnknown **ppEnumerator)
1194{
1195 struct InstalledRuntimeEnum *new_enum;
1196
1197 TRACE("%p\n", ppEnumerator);
1198
1199 new_enum = malloc(sizeof(*new_enum));
1200 if (!new_enum)
1201 return E_OUTOFMEMORY;
1202
1204 new_enum->ref = 1;
1205 new_enum->pos = 0;
1206
1207 *ppEnumerator = &new_enum->IEnumUnknown_iface;
1208
1209 return S_OK;
1210}
1211
1213 HANDLE hndProcess, IEnumUnknown **ppEnumerator)
1214{
1215 FIXME("%p %p\n", hndProcess, ppEnumerator);
1216
1217 return E_NOTIMPL;
1218}
1219
1221 RuntimeLoadedCallbackFnPtr pCallbackFunction)
1222{
1223 TRACE("%p\n", pCallbackFunction);
1224
1225 if(!pCallbackFunction)
1226 return E_POINTER;
1227
1228 if (GlobalCLRMetaHost.callback)
1230
1231 GlobalCLRMetaHost.callback = pCallbackFunction;
1232
1233 return S_OK;
1234}
1235
1237 REFIID riid, LPVOID *ppUnk)
1238{
1239 FIXME("%s %p\n", debugstr_guid(riid), ppUnk);
1240
1241 return E_NOTIMPL;
1242}
1243
1245{
1246 TRACE("%i\n", iExitCode);
1247
1249
1251 {
1252 /* search for a runtime and call System.Environment.Exit() */
1253 int i;
1254
1255 for (i=0; i<NUM_RUNTIMES; i++)
1256 if (runtimes[i].loaded_runtime)
1257 RuntimeHost_ExitProcess(runtimes[i].loaded_runtime, iExitCode);
1258 }
1259
1260 ExitProcess(iExitCode);
1261}
1262
1263static const struct ICLRMetaHostVtbl CLRMetaHost_vtbl =
1264{
1275};
1276
1277static struct CLRMetaHost GlobalCLRMetaHost = {
1278 { &CLRMetaHost_vtbl }
1279};
1280
1282{
1283 return ICLRMetaHost_QueryInterface(&GlobalCLRMetaHost.ICLRMetaHost_iface, riid, ppobj);
1284}
1285
1287{
1289};
1290
1292
1294{
1295 TRACE("%s %p\n", debugstr_guid(riid), obj);
1296
1297 if ( IsEqualGUID( riid, &IID_ICLRMetaHostPolicy ) ||
1299 {
1300 ICLRMetaHostPolicy_AddRef( iface );
1301 *obj = iface;
1302 return S_OK;
1303 }
1304
1305 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
1306
1307 *obj = NULL;
1308 return E_NOINTERFACE;
1309}
1310
1312{
1313 return 2;
1314}
1315
1317{
1318 return 1;
1319}
1320
1322 LPCWSTR pwzBinary, IStream *pCfgStream, LPWSTR pwzVersion, DWORD *pcchVersion,
1323 LPWSTR pwzImageVersion, DWORD *pcchImageVersion, DWORD *pdwConfigFlags, REFIID riid,
1324 LPVOID *ppRuntime)
1325{
1326 ICLRRuntimeInfo *result;
1327 HRESULT hr;
1329 const WCHAR *path = NULL;
1330 int flags = 0;
1331
1332 TRACE("%d %p %p %p %p %p %p %p %s %p\n", dwPolicyFlags, pwzBinary, pCfgStream,
1333 pwzVersion, pcchVersion, pwzImageVersion, pcchImageVersion, pdwConfigFlags,
1334 debugstr_guid(riid), ppRuntime);
1335
1336 if (pdwConfigFlags) {
1337 FIXME("ignoring config flags\n");
1338 *pdwConfigFlags = 0;
1339 }
1340
1341 if(dwPolicyFlags & METAHOST_POLICY_USE_PROCESS_IMAGE_PATH)
1342 {
1344 path = filename;
1345 }
1346 else if(pwzBinary)
1347 {
1348 path = pwzBinary;
1349 }
1350
1351 if(dwPolicyFlags & METAHOST_POLICY_APPLY_UPGRADE_POLICY)
1353
1354 hr = get_runtime_info(path, pwzImageVersion, NULL, pCfgStream, 0, flags, FALSE, &result);
1355 if (SUCCEEDED(hr))
1356 {
1357 if (pwzImageVersion)
1358 {
1359 /* Ignoring errors on purpose */
1360 ICLRRuntimeInfo_GetVersionString(result, pwzImageVersion, pcchImageVersion);
1361 }
1362
1363 hr = ICLRRuntimeInfo_QueryInterface(result, riid, ppRuntime);
1364
1365 ICLRRuntimeInfo_Release(result);
1366 }
1367
1368 TRACE("<- 0x%08lx\n", hr);
1369
1370 return hr;
1371}
1372
1373static const struct ICLRMetaHostPolicyVtbl CLRMetaHostPolicy_vtbl =
1374{
1379};
1380
1383};
1384
1386{
1387 return ICLRMetaHostPolicy_QueryInterface(&GlobalCLRMetaHostPolicy.ICLRMetaHostPolicy_iface, riid, ppobj);
1388}
1389
1390/*
1391 * Assembly search override settings:
1392 *
1393 * WINE_MONO_OVERRIDES=*,Gac=n
1394 * Never search the Windows GAC for libraries.
1395 *
1396 * WINE_MONO_OVERRIDES=*,MonoGac=n
1397 * Never search the Mono GAC for libraries.
1398 *
1399 * WINE_MONO_OVERRIDES=*,PrivatePath=n
1400 * Never search the AppDomain search path for libraries.
1401 *
1402 * WINE_MONO_OVERRIDES=Microsoft.Xna.Framework,Gac=n
1403 * Never search the Windows GAC for Microsoft.Xna.Framework
1404 *
1405 * WINE_MONO_OVERRIDES=Microsoft.Xna.Framework.*,Gac=n;Microsoft.Xna.Framework.GamerServices,Gac=y
1406 * Never search the Windows GAC for Microsoft.Xna.Framework, or any library starting
1407 * with Microsoft.Xna.Framework, except for Microsoft.Xna.Framework.GamerServices
1408 */
1409
1410/* assembly search override flags */
1411#define ASSEMBLY_SEARCH_GAC 1
1412#define ASSEMBLY_SEARCH_UNDEFINED 2
1413#define ASSEMBLY_SEARCH_PRIVATEPATH 4
1414#define ASSEMBLY_SEARCH_MONOGAC 8
1415#define ASSEMBLY_SEARCH_DEFAULT (ASSEMBLY_SEARCH_GAC|ASSEMBLY_SEARCH_PRIVATEPATH|ASSEMBLY_SEARCH_MONOGAC)
1416
1417typedef struct override_entry {
1418 char *name;
1420 struct list entry;
1422
1424
1425#define IS_OPTION_TRUE(ch) \
1426 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
1427#define IS_OPTION_FALSE(ch) \
1428 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
1429
1430static void parse_override_entry(override_entry *entry, const char *string, int string_len)
1431{
1432 const char *next_key, *equals, *value;
1433 UINT kvp_len, key_len;
1434
1436
1437 while (string && string_len > 0)
1438 {
1439 next_key = memchr(string, ',', string_len);
1440
1441 if (next_key)
1442 {
1443 kvp_len = next_key - string;
1444 next_key++;
1445 }
1446 else
1447 kvp_len = string_len;
1448
1449 equals = memchr(string, '=', kvp_len);
1450
1451 if (equals)
1452 {
1453 key_len = equals - string;
1454 value = equals + 1;
1455 switch (key_len) {
1456 case 3:
1457 if (!_strnicmp(string, "gac", 3)) {
1458 if (IS_OPTION_TRUE(*value))
1459 entry->flags |= ASSEMBLY_SEARCH_GAC;
1460 else if (IS_OPTION_FALSE(*value))
1461 entry->flags &= ~ASSEMBLY_SEARCH_GAC;
1462 }
1463 break;
1464 case 7:
1465 if (!_strnicmp(string, "monogac", 7)) {
1466 if (IS_OPTION_TRUE(*value))
1468 else if (IS_OPTION_FALSE(*value))
1469 entry->flags &= ~ASSEMBLY_SEARCH_MONOGAC;
1470 }
1471 break;
1472 case 11:
1473 if (!_strnicmp(string, "privatepath", 11)) {
1474 if (IS_OPTION_TRUE(*value))
1476 else if (IS_OPTION_FALSE(*value))
1477 entry->flags &= ~ASSEMBLY_SEARCH_PRIVATEPATH;
1478 }
1479 break;
1480 default:
1481 break;
1482 }
1483 }
1484
1485 string = next_key;
1486 string_len -= kvp_len + 1;
1487 }
1488}
1489
1491{
1492 const char *override_string = getenv("WINE_MONO_OVERRIDES");
1493 struct override_entry *entry;
1494
1495 if (override_string)
1496 {
1497 const char *entry_start;
1498
1499 entry_start = override_string;
1500
1501 while (entry_start && *entry_start)
1502 {
1503 const char *next_entry, *basename_end;
1504 UINT entry_len;
1505
1506 next_entry = strchr(entry_start, ';');
1507
1508 if (next_entry)
1509 {
1510 entry_len = next_entry - entry_start;
1511 next_entry++;
1512 }
1513 else
1514 entry_len = strlen(entry_start);
1515
1516 basename_end = memchr(entry_start, ',', entry_len);
1517
1518 if (!basename_end)
1519 {
1520 entry_start = next_entry;
1521 continue;
1522 }
1523
1524 entry = calloc(1, sizeof(*entry));
1525 if (!entry)
1526 {
1527 ERR("out of memory\n");
1528 break;
1529 }
1530
1531 entry->name = calloc(1, basename_end - entry_start + 1);
1532 if (!entry->name)
1533 {
1534 ERR("out of memory\n");
1535 free(entry);
1536 break;
1537 }
1538
1539 memcpy(entry->name, entry_start, basename_end - entry_start);
1540
1541 entry_len -= basename_end - entry_start + 1;
1542 entry_start = basename_end + 1;
1543
1544 parse_override_entry(entry, entry_start, entry_len);
1545
1547
1548 entry_start = next_entry;
1549 }
1550 }
1551
1552 return TRUE;
1553}
1554
1555static DWORD get_basename_search_flags(const char *basename, MonoAssemblyName *aname, HKEY userkey, HKEY appkey)
1556{
1557 struct override_entry *entry;
1558 char buffer[256];
1560 static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
1561
1563
1565 {
1566 if (strcmp(basename, entry->name) == 0)
1567 {
1568 return entry->flags;
1569 }
1570 }
1571
1572 buffer_size = sizeof(buffer);
1573 if (appkey && !RegQueryValueExA(appkey, basename, 0, NULL, (LPBYTE)buffer, &buffer_size))
1574 {
1575 override_entry reg_entry;
1576
1577 memset(&reg_entry, 0, sizeof(reg_entry));
1578
1580
1581 return reg_entry.flags;
1582 }
1583
1584 buffer_size = sizeof(buffer);
1585 if (userkey && !RegQueryValueExA(userkey, basename, 0, NULL, (LPBYTE)buffer, &buffer_size))
1586 {
1587 override_entry reg_entry;
1588
1589 memset(&reg_entry, 0, sizeof(reg_entry));
1590
1592
1593 return reg_entry.flags;
1594 }
1595
1596 if (strcmp(basename, "Microsoft.Xna.Framework.*") == 0 &&
1597 mono_assembly_name_get_version(aname, NULL, NULL, NULL) == 4)
1598 /* Use FNA as a replacement for XNA4. */
1600
1602}
1603
1605{
1606 static const WCHAR subkeyW[] = {'\\','M','o','n','o','\\','A','s','m','O','v','e','r','r','i','d','e','s',0};
1607 WCHAR bufferW[MAX_PATH+18];
1608 HKEY appkey = 0;
1609 DWORD len;
1610
1611 len = (GetModuleFileNameW( 0, bufferW, MAX_PATH ));
1612 if (len && len < MAX_PATH)
1613 {
1614 HKEY tmpkey;
1615 WCHAR *p, *appname = bufferW;
1616 if ((p = wcsrchr( appname, '/' ))) appname = p + 1;
1617 if ((p = wcsrchr( appname, '\\' ))) appname = p + 1;
1618 lstrcatW( appname, subkeyW );
1619 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Mono\AsmOverrides */
1620 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
1621 {
1622 if (RegOpenKeyW( tmpkey, appname, &appkey )) appkey = 0;
1623 RegCloseKey( tmpkey );
1624 }
1625 }
1626
1627 return appkey;
1628}
1629
1631{
1632 const char *name = mono_assembly_name_get_name(aname);
1633 char *name_copy, *name_end;
1634 DWORD result;
1635 HKEY appkey = 0, userkey;
1636
1637 /* @@ Wine registry key: HKCU\Software\Wine\Mono\AsmOverrides */
1638 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Mono\\AsmOverrides", &userkey )) userkey = 0;
1639
1640 appkey = get_app_overrides_key();
1641
1642 result = get_basename_search_flags(name, aname, userkey, appkey);
1644 {
1645 if (userkey) RegCloseKey(userkey);
1646 if (appkey) RegCloseKey(appkey);
1647 return result;
1648 }
1649
1650 name_copy = malloc(strlen(name) + 3);
1651 if (!name_copy)
1652 {
1653 ERR("out of memory\n");
1654 if (userkey) RegCloseKey(userkey);
1655 if (appkey) RegCloseKey(appkey);
1657 }
1658
1659 strcpy(name_copy, name);
1660 name_end = name_copy + strlen(name);
1661
1662 do
1663 {
1664 strcpy(name_end, ".*");
1665 result = get_basename_search_flags(name_copy, aname, userkey, appkey);
1666 if (result != ASSEMBLY_SEARCH_UNDEFINED) break;
1667
1668 *name_end = 0;
1669 name_end = strrchr(name_copy, '.');
1670 } while (name_end != NULL);
1671
1672 /* default flags */
1674 {
1675 result = get_basename_search_flags("*", aname, userkey, appkey);
1678 }
1679
1680 free(name_copy);
1681 if (appkey) RegCloseKey(appkey);
1682 if (userkey) RegCloseKey(userkey);
1683
1684 return result;
1685}
1686
1687HRESULT get_file_from_strongname(WCHAR* stringnameW, WCHAR* assemblies_path, int path_length)
1688{
1689 HRESULT hr=S_OK;
1690 IAssemblyCache *asmcache;
1692 static const WCHAR fusiondll[] = {'f','u','s','i','o','n',0};
1693 HMODULE hfusion=NULL;
1694 static HRESULT (WINAPI *pCreateAssemblyCache)(IAssemblyCache**,DWORD);
1695
1696 if (!pCreateAssemblyCache)
1697 {
1698 hr = LoadLibraryShim(fusiondll, NULL, NULL, &hfusion);
1699
1700 if (SUCCEEDED(hr))
1701 {
1702 pCreateAssemblyCache = (void*)GetProcAddress(hfusion, "CreateAssemblyCache");
1703 if (!pCreateAssemblyCache)
1704 hr = E_FAIL;
1705 }
1706 }
1707
1708 if (SUCCEEDED(hr))
1709 hr = pCreateAssemblyCache(&asmcache, 0);
1710
1711 if (SUCCEEDED(hr))
1712 {
1713 info.cbAssemblyInfo = sizeof(info);
1714 info.pszCurrentAssemblyPathBuf = assemblies_path;
1715 info.cchBuf = path_length;
1716 assemblies_path[0] = 0;
1717
1718 hr = IAssemblyCache_QueryAssemblyInfo(asmcache, 0, stringnameW, &info);
1719
1720 IAssemblyCache_Release(asmcache);
1721 }
1722
1723 return hr;
1724}
1725
1727{
1730 char *pathA;
1731
1732 if (!(pathA = WtoA(path))) return NULL;
1733
1735 free(pathA);
1736
1737 if (result) TRACE("found: %s\n", debugstr_w(path));
1738 return result;
1739}
1740
1741static MonoAssembly* CDECL mono_assembly_preload_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data)
1742{
1743 int flags = 0;
1744 return wine_mono_assembly_preload_hook_v2_fn(aname, assemblies_path, &flags, user_data);
1745}
1746
1747static MonoAssembly* CDECL wine_mono_assembly_preload_hook_fn(MonoAssemblyName *aname, char **assemblies_path, int *halt_search, void *user_data)
1748{
1749 int flags = 0;
1752 *halt_search = 1;
1753 return result;
1754}
1755
1757{
1758 HRESULT hr;
1760 char *stringname=NULL;
1761 const char *assemblyname;
1762 const char *culture;
1763 LPWSTR stringnameW, cultureW;
1764 int stringnameW_size, cultureW_size;
1766 char *pathA;
1768 DWORD search_flags;
1769 int i;
1770 static const WCHAR dotdllW[] = {'.','d','l','l',0};
1771 static const WCHAR dotexeW[] = {'.','e','x','e',0};
1772
1773 stringname = mono_stringify_assembly_name(aname);
1774 assemblyname = mono_assembly_name_get_name(aname);
1776 if (culture)
1777 {
1778 cultureW_size = MultiByteToWideChar(CP_UTF8, 0, culture, -1, NULL, 0);
1779 cultureW = malloc(cultureW_size * sizeof(WCHAR));
1780 if (cultureW) MultiByteToWideChar(CP_UTF8, 0, culture, -1, cultureW, cultureW_size);
1781 }
1782 else cultureW = NULL;
1783
1784 TRACE("%s\n", debugstr_a(stringname));
1785
1786 if (!stringname || !assemblyname) return NULL;
1787
1788 search_flags = get_assembly_search_flags(aname);
1789 if (private_path && (search_flags & ASSEMBLY_SEARCH_PRIVATEPATH) != 0)
1790 {
1791 stringnameW_size = MultiByteToWideChar(CP_UTF8, 0, assemblyname, -1, NULL, 0);
1792 stringnameW = malloc(stringnameW_size * sizeof(WCHAR));
1793 if (stringnameW)
1794 {
1795 MultiByteToWideChar(CP_UTF8, 0, assemblyname, -1, stringnameW, stringnameW_size);
1796 for (i = 0; private_path[i] != NULL; i++)
1797 {
1798 /* This is the lookup order used in Mono */
1799 /* 1st try: [culture]/[name].dll (culture may be empty) */
1801 if (cultureW) PathAppendW(path, cultureW);
1802 PathAppendW(path, stringnameW);
1803 wcscat(path, dotdllW);
1805 if (result) break;
1806
1807 /* 2nd try: [culture]/[name].exe (culture may be empty) */
1808 wcscpy(path + wcslen(path) - wcslen(dotdllW), dotexeW);
1810 if (result) break;
1811
1812 /* 3rd try: [culture]/[name]/[name].dll (culture may be empty) */
1813 path[wcslen(path) - wcslen(dotexeW)] = 0;
1814 PathAppendW(path, stringnameW);
1815 wcscat(path, dotdllW);
1817 if (result) break;
1818
1819 /* 4th try: [culture]/[name]/[name].exe (culture may be empty) */
1820 wcscpy(path + wcslen(path) - wcslen(dotdllW), dotexeW);
1822 if (result) break;
1823 }
1824 free(stringnameW);
1825 if (result) goto done;
1826 }
1827 }
1828
1829 if ((search_flags & ASSEMBLY_SEARCH_GAC) != 0)
1830 {
1831 stringnameW_size = MultiByteToWideChar(CP_UTF8, 0, stringname, -1, NULL, 0);
1832
1833 stringnameW = malloc(stringnameW_size * sizeof(WCHAR));
1834 if (stringnameW)
1835 {
1836 MultiByteToWideChar(CP_UTF8, 0, stringname, -1, stringnameW, stringnameW_size);
1837
1838 hr = get_file_from_strongname(stringnameW, path, MAX_PATH);
1839
1840 free(stringnameW);
1841 }
1842 else
1843 hr = E_OUTOFMEMORY;
1844
1845 if (SUCCEEDED(hr))
1846 {
1847 TRACE("found: %s\n", debugstr_w(path));
1848
1849 pathA = WtoA(path);
1850
1851 if (pathA)
1852 {
1854
1855 if (!result)
1856 ERR("Failed to load %s, status=%u\n", debugstr_w(path), stat);
1857
1858 free(pathA);
1859
1860 if (result)
1861 {
1863 goto done;
1864 }
1865 }
1866 }
1867 }
1868 else
1869 TRACE("skipping Windows GAC search due to override setting\n");
1870
1872 {
1873 if (search_flags & ASSEMBLY_SEARCH_MONOGAC)
1874 {
1876
1877 if (result)
1878 {
1879 TRACE("found in Mono GAC\n");
1881 goto done;
1882 }
1883 }
1884 else
1885 {
1887 TRACE("skipping Mono GAC search due to override setting\n");
1888 }
1889 }
1890
1891 if ((search_flags & ASSEMBLY_SEARCH_PRIVATEPATH) == 0)
1892 {
1893 TRACE("skipping AppDomain search path due to override setting\n");
1895 }
1896
1897done:
1898 free(cultureW);
1899 mono_free(stringname);
1900
1901 return result;
1902}
1903
1905 IStream *config_stream, DWORD startup_flags, DWORD runtimeinfo_flags,
1906 BOOL legacy, ICLRRuntimeInfo **result)
1907{
1908 static const WCHAR dotconfig[] = {'.','c','o','n','f','i','g',0};
1909 static const DWORD supported_startup_flags = 0;
1910 static const DWORD supported_runtime_flags = RUNTIME_INFO_UPGRADE_VERSION;
1911 int i;
1912 WCHAR local_version[MAX_PATH];
1913 ULONG local_version_size = MAX_PATH;
1914 WCHAR local_config_file[MAX_PATH];
1915 HRESULT hr;
1916 parsed_config_file parsed_config;
1917
1918 if (startup_flags & ~supported_startup_flags)
1919 FIXME("unsupported startup flags %lx\n", startup_flags & ~supported_startup_flags);
1920
1921 if (runtimeinfo_flags & ~supported_runtime_flags)
1922 FIXME("unsupported runtimeinfo flags %lx\n", runtimeinfo_flags & ~supported_runtime_flags);
1923
1924 if (exefile && !exefile[0])
1925 exefile = NULL;
1926
1927 if (exefile && !config_file && !config_stream)
1928 {
1929 lstrcpyW(local_config_file, exefile);
1930 lstrcatW(local_config_file, dotconfig);
1931
1932 config_file = local_config_file;
1933 }
1934
1935 if (config_file || config_stream)
1936 {
1937 BOOL found = FALSE;
1938 if (config_file)
1939 hr = parse_config_file(config_file, &parsed_config);
1940 else
1941 hr = parse_config_stream(config_stream, &parsed_config);
1942
1943 if (SUCCEEDED(hr))
1944 {
1947 {
1948 hr = get_runtime(entry->version, TRUE, &IID_ICLRRuntimeInfo, (void**)result);
1949 if (SUCCEEDED(hr))
1950 {
1951 found = TRUE;
1952 break;
1953 }
1954 }
1955 }
1956 else
1957 {
1958 WARN("failed to parse config file %s, hr=%lx\n", debugstr_w(config_file), hr);
1959 }
1960
1961 free_parsed_config_file(&parsed_config);
1962
1963 if (found)
1964 return S_OK;
1965 }
1966
1967 if (exefile && !version)
1968 {
1970
1971 hr = CLRMetaHost_GetVersionFromFile(0, exefile, local_version, &local_version_size);
1972
1973 version = local_version;
1974
1975 if (FAILED(hr)) return hr;
1976
1977 /* When running an executable, specifically when getting the version number from
1978 * the exe, native accepts a matching major.minor with build <= expected build. */
1980 {
1981 ERR("Cannot parse %s\n", debugstr_w(version));
1982 return CLR_E_SHIM_RUNTIME;
1983 }
1984
1985 if (legacy)
1986 i = 3;
1987 else
1988 i = NUM_RUNTIMES;
1989
1990 while (i--)
1991 {
1992 if (runtimes[i].major == major && runtimes[i].minor == minor && runtimes[i].build >= build)
1993 {
1994 return ICLRRuntimeInfo_QueryInterface(&runtimes[i].ICLRRuntimeInfo_iface,
1995 &IID_ICLRRuntimeInfo, (void **)result);
1996 }
1997 }
1998 }
1999
2000 if (version)
2001 {
2002 hr = CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo, (void**)result);
2003 if(SUCCEEDED(hr))
2004 return hr;
2005 }
2006
2007 if (runtimeinfo_flags & RUNTIME_INFO_UPGRADE_VERSION)
2008 {
2010
2012 {
2013 ERR("Cannot parse %s\n", debugstr_w(version));
2014 return CLR_E_SHIM_RUNTIME;
2015 }
2016
2017 if (legacy)
2018 i = 3;
2019 else
2020 i = NUM_RUNTIMES;
2021
2022 while (i--)
2023 {
2024 /* Must be greater or equal to the version passed in. */
2025 if (!version || ((runtimes[i].major >= major && runtimes[i].minor >= minor && runtimes[i].build >= build) ||
2026 (runtimes[i].major >= major && runtimes[i].minor > minor) ||
2027 (runtimes[i].major > major)))
2028 {
2029 return ICLRRuntimeInfo_QueryInterface(&runtimes[i].ICLRRuntimeInfo_iface,
2030 &IID_ICLRRuntimeInfo, (void **)result);
2031 }
2032 }
2033
2034 return CLR_E_SHIM_RUNTIME;
2035 }
2036
2037 return CLR_E_SHIM_RUNTIME;
2038}
#define stat
Definition: acwin.h:99
static long path_length
Definition: maze.c:116
unsigned int dir
Definition: maze.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: list.h:37
#define CLR_E_SHIM_RUNTIME
Definition: corerror.h:226
#define HOST_E_INVALIDOPERATION
Definition: corerror.h:914
void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode)
HRESULT RuntimeHost_GetInterface(RuntimeHost *This, REFCLSID clsid, REFIID riid, void **ppv)
HRESULT RuntimeHost_Construct(CLRRuntimeInfo *runtime_version, RuntimeHost **result)
WCHAR ** private_path
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define CDECL
Definition: compat.h:29
#define GetProcessHeap()
Definition: compat.h:736
#define wcsrchr
Definition: compat.h:16
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:754
#define MultiByteToWideChar
Definition: compat.h:110
#define LoadLibraryW(x)
Definition: compat.h:747
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
static const WCHAR culture[]
Definition: asmname.c:67
static DWORD cchBuffer
Definition: fusion.c:85
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2271
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1331
BOOL WINAPI InitOnceExecuteOnce(_Inout_ PINIT_ONCE InitOnce, _In_ __callback PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, _Outptr_opt_result_maybenull_ LPVOID *Context)
Definition: InitOnce.c:12
const WCHAR system_dir[]
Definition: file.c:68
static void basename(LPCWSTR path, LPWSTR name)
Definition: profile.c:38
HRESULT parse_config_stream(IStream *stream, parsed_config_file *result)
Definition: config.c:658
HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result)
Definition: config.c:678
void free_parsed_config_file(parsed_config_file *file)
Definition: config.c:696
MonoObject *CDECL * mono_object_new(MonoDomain *domain, MonoClass *klass)
static HRESULT WINAPI CLRRuntimeInfo_LoadLibrary(ICLRRuntimeInfo *iface, LPCWSTR pwzDllName, HMODULE *phndModule)
Definition: metahost.c:605
HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file, IStream *config_stream, DWORD startup_flags, DWORD runtimeinfo_flags, BOOL legacy, ICLRRuntimeInfo **result)
Definition: metahost.c:1904
static HRESULT WINAPI CLRRuntimeInfo_IsStarted(ICLRRuntimeInfo *iface, BOOL *pbStarted, DWORD *pdwStartupFlags)
Definition: metahost.c:677
static struct CLRRuntimeInfo runtimes[NUM_RUNTIMES]
Definition: metahost.c:52
#define IS_OPTION_TRUE(ch)
Definition: metahost.c:1425
static DWORD get_basename_search_flags(const char *basename, MonoAssemblyName *aname, HKEY userkey, HKEY appkey)
Definition: metahost.c:1555
static HRESULT WINAPI CLRRuntimeInfo_GetInterface(ICLRRuntimeInfo *iface, REFCLSID rclsid, REFIID riid, LPVOID *ppUnk)
Definition: metahost.c:629
static HRESULT WINAPI CLRRuntimeInfo_GetRuntimeDirectory(ICLRRuntimeInfo *iface, LPWSTR pwzBuffer, DWORD *pcchBuffer)
Definition: metahost.c:550
static HRESULT WINAPI InstalledRuntimeEnum_Skip(IEnumUnknown *iface, ULONG celt)
Definition: metahost.c:981
MonoImage *CDECL * mono_image_open_from_module_handle(HMODULE module_handle, char *fname, UINT has_entry_point, MonoImageOpenStatus *status)
MonoImage *CDECL * mono_get_corlib(void)
static ULONG WINAPI InstalledRuntimeEnum_Release(IEnumUnknown *iface)
Definition: metahost.c:936
static ULONG WINAPI CLRRuntimeInfo_AddRef(ICLRRuntimeInfo *iface)
Definition: metahost.c:490
MonoImage *CDECL * mono_assembly_get_image(MonoAssembly *assembly)
void expect_no_runtimes(void)
Definition: metahost.c:454
static HRESULT WINAPI InstalledRuntimeEnum_Reset(IEnumUnknown *iface)
Definition: metahost.c:1003
MonoThread *CDECL * mono_thread_attach(MonoDomain *domain)
static BOOL get_mono_path_unix(const char *unix_dir, LPWSTR path)
Definition: metahost.c:819
MonoDomain *CDECL * mono_object_get_domain(MonoObject *obj)
const char *CDECL * mono_assembly_name_get_culture(MonoAssemblyName *aname)
static char * get_exe_basename_utf8(void)
Definition: metahost.c:351
static void CDECL set_log_handler_dummy(MonoLogCallback callback, void *user_data)
Definition: metahost.c:159
static HRESULT WINAPI CLRRuntimeInfo_LoadErrorString(ICLRRuntimeInfo *iface, UINT iResourceID, LPWSTR pwzBuffer, DWORD *pcchBuffer, LONG iLocaleid)
Definition: metahost.c:597
static const struct ICLRRuntimeInfoVtbl CLRRuntimeInfoVtbl
Definition: metahost.c:48
static BOOL parse_runtime_version(LPCWSTR version, DWORD *major, DWORD *minor, DWORD *build)
Definition: metahost.c:1081
static HRESULT WINAPI CLRMetaHost_EnumerateInstalledRuntimes(ICLRMetaHost *iface, IEnumUnknown **ppEnumerator)
Definition: metahost.c:1192
static struct InstalledRuntimeEnum * impl_from_IEnumUnknown(IEnumUnknown *iface)
Definition: metahost.c:900
static const struct IEnumUnknownVtbl InstalledRuntimeEnum_Vtbl
Definition: metahost.c:898
MonoAssembly int argc
Definition: metahost.c:107
HRESULT WINAPI CLRMetaHost_GetVersionFromFile(ICLRMetaHost *iface, LPCWSTR pwzFilePath, LPWSTR pwzBuffer, DWORD *pcchBuffer)
Definition: metahost.c:1157
struct _MonoProfilerDesc * MonoProfilerHandle
Definition: metahost.c:83
static BOOL get_mono_path_registry(LPWSTR path)
Definition: metahost.c:765
static BOOL is_mono_shutdown
Definition: metahost.c:81
#define ASSEMBLY_SEARCH_DEFAULT
Definition: metahost.c:1415
MonoObject *CDECL * mono_runtime_invoke(MonoMethod *method, void *obj, void **params, MonoObject **exc)
static struct list env_overrides
Definition: metahost.c:1423
HRESULT get_file_from_strongname(WCHAR *stringnameW, WCHAR *assemblies_path, int path_length)
Definition: metahost.c:1687
static MonoProfileFunc shutdown_callback
Definition: metahost.c:117
WORD WORD WORD * revision
Definition: metahost.c:91
HRESULT CLRMetaHostPolicy_CreateInstance(REFIID riid, void **ppobj)
Definition: metahost.c:1385
static HRESULT WINAPI CLRMetaHost_QueryInterface(ICLRMetaHost *iface, REFIID riid, void **ppvObject)
Definition: metahost.c:1044
static HRESULT CLRRuntimeInfo_GetRuntimeHost(CLRRuntimeInfo *This, RuntimeHost **result)
Definition: metahost.c:410
#define NUM_RUNTIMES
Definition: metahost.c:50
#define ASSEMBLY_SEARCH_GAC
Definition: metahost.c:1411
MonoAssembly * assembly
Definition: metahost.c:107
static HRESULT WINAPI InstalledRuntimeEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
Definition: metahost.c:1014
void(CDECL * MonoProfilerRuntimeShutdownBeginCallback)(MonoProfiler *prof)
Definition: metahost.c:85
static const WCHAR libmono2_arch_dll[]
Definition: metahost.c:717
MonoString *CDECL * mono_string_new(MonoDomain *domain, const char *str)
static HRESULT WINAPI CLRRuntimeInfo_IsLoadable(ICLRRuntimeInfo *iface, BOOL *pbLoadable)
Definition: metahost.c:646
MonoDomain *CDECL * mono_domain_get_by_id(int id)
#define ASSEMBLY_SEARCH_MONOGAC
Definition: metahost.c:1414
MonoAssembly *CDECL * mono_assembly_open(const char *filename, MonoImageOpenStatus *status)
static HRESULT WINAPI CLRRuntimeInfo_GetProcAddress(ICLRRuntimeInfo *iface, LPCSTR pszProcName, LPVOID *ppProc)
Definition: metahost.c:621
static HRESULT load_mono(LPCWSTR mono_path)
Definition: metahost.c:163
static HRESULT WINAPI thread_set_fn(void)
Definition: metahost.c:398
static BOOL WINAPI parse_env_overrides(INIT_ONCE *once, void *param, void **context)
Definition: metahost.c:1490
static ULONG WINAPI metahostpolicy_Release(ICLRMetaHostPolicy *iface)
Definition: metahost.c:1316
MonoDomain *CDECL * mono_domain_get(void)
static CLRRuntimeInfo * impl_from_ICLRRuntimeInfo(ICLRRuntimeInfo *iface)
Definition: metahost.c:463
MonoMethod *CDECL * mono_object_get_virtual_method(MonoObject *obj, MonoMethod *method)
static ULONG WINAPI InstalledRuntimeEnum_AddRef(IEnumUnknown *iface)
Definition: metahost.c:926
static void CDECL set_print_handler_dummy(MonoPrintCallback callback)
Definition: metahost.c:155
static HRESULT WINAPI CLRRuntimeInfo_BindAsLegacyV2Runtime(ICLRRuntimeInfo *iface)
Definition: metahost.c:670
BOOL is_mono_started
Definition: metahost.c:80
static HRESULT WINAPI CLRRuntimeInfo_GetVersionString(ICLRRuntimeInfo *iface, LPWSTR pwzBuffer, DWORD *pcchBuffer)
Definition: metahost.c:500
static char *CDECL * mono_stringify_assembly_name(MonoAssemblyName *aname)
static MonoAssembly *CDECL * wine_mono_assembly_load_from_gac(MonoAssemblyName *aname, MonoImageOpenStatus *status, int refonly)
static const struct ICLRMetaHostVtbl CLRMetaHost_vtbl
Definition: metahost.c:1263
#define ASSEMBLY_SEARCH_UNDEFINED
Definition: metahost.c:1412
static DWORD get_assembly_search_flags(MonoAssemblyName *aname)
Definition: metahost.c:1630
MonoAssembly int char * argv[]
Definition: metahost.c:107
static const char * config_dir
Definition: metahost.c:124
static BOOL get_mono_path_dos(const WCHAR *dir, LPWSTR path)
Definition: metahost.c:792
static const struct ICLRMetaHostPolicyVtbl CLRMetaHostPolicy_vtbl
Definition: metahost.c:1373
static void parse_override_entry(override_entry *entry, const char *string, int string_len)
Definition: metahost.c:1430
static MonoAssembly *CDECL wine_mono_assembly_preload_hook_v2_fn(MonoAssemblyName *aname, char **assemblies_path, int *flags, void *user_data)
Definition: metahost.c:1756
#define LOAD_OPT_MONO_FUNCTION(x, default)
static void CDECL set_crash_chaining_dummy(BOOL crash_chaining)
Definition: metahost.c:151
static CRITICAL_SECTION runtime_list_cs
Definition: metahost.c:59
#define LOAD_MONO_FUNCTION(x)
static MonoAssembly *CDECL mono_assembly_preload_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data)
Definition: metahost.c:1741
MonoAssembly *CDECL * mono_assembly_load_from(MonoImage *image, const char *fname, MonoImageOpenStatus *status)
#define IS_OPTION_FALSE(ch)
Definition: metahost.c:1427
const char * base_dir
Definition: metahost.c:101
static ULONG WINAPI CLRRuntimeInfo_Release(ICLRRuntimeInfo *iface)
Definition: metahost.c:495
MonoType *CDECL * mono_reflection_type_from_name(char *name, MonoImage *image)
static struct CLRMetaHost GlobalCLRMetaHost
Definition: metahost.c:76
void *CDECL * mono_object_unbox(MonoObject *obj)
static HRESULT WINAPI CLRRuntimeInfo_IsLoaded(ICLRRuntimeInfo *iface, HANDLE hndProcess, BOOL *pbLoaded)
Definition: metahost.c:589
const char *CDECL * mono_assembly_name_get_name(MonoAssemblyName *aname)
static BOOL get_install_root(LPWSTR install_dir)
Definition: metahost.c:528
static HRESULT WINAPI CLRRuntimeInfo_SetDefaultStartupFlags(ICLRRuntimeInfo *iface, DWORD dwStartupFlags, LPCWSTR pwzHostConfigFile)
Definition: metahost.c:654
WORD WORD * build
Definition: metahost.c:91
MonoClass *CDECL * mono_class_from_mono_type(MonoType *type)
MonoMethod *CDECL * mono_class_get_method_from_name(MonoClass *klass, const char *name, int param_count)
const char const char * config_file_name
Definition: metahost.c:101
void *CDECL * mono_marshal_get_vtfixup_ftnptr(MonoImage *image, DWORD token, WORD type)
static HRESULT get_runtime(LPCWSTR pwzVersion, BOOL allow_short, REFIID iid, LPVOID *ppRuntime)
Definition: metahost.c:1120
static MonoImage *CDECL * mono_image_open(const char *fname, MonoImageOpenStatus *status)
static HRESULT WINAPI CLRMetaHost_QueryLegacyV2RuntimeBinding(ICLRMetaHost *iface, REFIID riid, LPVOID *ppUnk)
Definition: metahost.c:1236
HRESULT CLRMetaHost_CreateInstance(REFIID riid, void **ppobj)
Definition: metahost.c:1281
static HKEY get_app_overrides_key(void)
Definition: metahost.c:1604
static BOOL isDigit(WCHAR c)
Definition: metahost.c:1076
BOOL get_mono_path(LPWSTR path, BOOL skip_local)
Definition: metahost.c:874
static void * user_data
Definition: metahost.c:106
static ULONG WINAPI CLRMetaHost_Release(ICLRMetaHost *iface)
Definition: metahost.c:1071
static HRESULT WINAPI CLRMetaHost_RequestRuntimeLoadedNotification(ICLRMetaHost *iface, RuntimeLoadedCallbackFnPtr pCallbackFunction)
Definition: metahost.c:1220
static HMODULE mono_handle
Definition: metahost.c:78
static MonoImage *CDECL image_open_module_handle_dummy(HMODULE module_handle, char *fname, UINT has_entry_point, MonoImageOpenStatus *status)
Definition: metahost.c:145
static HRESULT WINAPI CLRMetaHost_EnumerateLoadedRuntimes(ICLRMetaHost *iface, HANDLE hndProcess, IEnumUnknown **ppEnumerator)
Definition: metahost.c:1212
static MonoAssembly * mono_assembly_try_load(WCHAR *path)
Definition: metahost.c:1726
MonoClass *CDECL * mono_class_from_name(MonoImage *image, const char *name_space, const char *name)
HRESULT ICLRRuntimeInfo_GetRuntimeHost(ICLRRuntimeInfo *iface, RuntimeHost **result)
Definition: metahost.c:703
static HRESULT WINAPI InstalledRuntimeEnum_QueryInterface(IEnumUnknown *iface, REFIID riid, void **ppvObject)
Definition: metahost.c:905
static HRESULT WINAPI CLRRuntimeInfo_QueryInterface(ICLRRuntimeInfo *iface, REFIID riid, void **ppvObject)
Definition: metahost.c:468
BOOL force
Definition: metahost.c:100
static CRITICAL_SECTION_DEBUG runtime_list_cs_debug
Definition: metahost.c:60
static struct CLRMetaHostPolicy GlobalCLRMetaHostPolicy
Definition: metahost.c:1291
static BOOL get_mono_path_local(LPWSTR path)
Definition: metahost.c:747
static BOOL get_mono_path_datadir(LPWSTR path)
Definition: metahost.c:843
static HRESULT WINAPI metahostpolicy_QueryInterface(ICLRMetaHostPolicy *iface, REFIID riid, void **obj)
Definition: metahost.c:1293
static HRESULT WINAPI thread_unset_fn(void)
Definition: metahost.c:404
static HRESULT WINAPI metahostpolicy_GetRequestedRuntime(ICLRMetaHostPolicy *iface, METAHOST_POLICY_FLAGS dwPolicyFlags, LPCWSTR pwzBinary, IStream *pCfgStream, LPWSTR pwzVersion, DWORD *pcchVersion, LPWSTR pwzImageVersion, DWORD *pcchImageVersion, DWORD *pdwConfigFlags, REFIID riid, LPVOID *ppRuntime)
Definition: metahost.c:1321
#define ASSEMBLY_SEARCH_PRIVATEPATH
Definition: metahost.c:1413
HRESULT WINAPI CLRMetaHost_ExitProcess(ICLRMetaHost *iface, INT32 iExitCode)
Definition: metahost.c:1244
static BOOL find_mono_dll(LPCWSTR path, LPWSTR dll_path)
Definition: metahost.c:720
static MonoAssembly *CDECL wine_mono_assembly_preload_hook_fn(MonoAssemblyName *aname, char **assemblies_path, int *search_path, void *user_data)
Definition: metahost.c:1747
MonoDomain *CDECL * mono_jit_init_version(const char *domain_name, const char *runtime_version)
static ULONG WINAPI metahostpolicy_AddRef(ICLRMetaHostPolicy *iface)
Definition: metahost.c:1311
WORD * minor
Definition: metahost.c:91
static HRESULT WINAPI InstalledRuntimeEnum_Next(IEnumUnknown *iface, ULONG celt, IUnknown **rgelt, ULONG *pceltFetched)
Definition: metahost.c:951
static HRESULT WINAPI CLRRuntimeInfo_GetDefaultStartupFlags(ICLRRuntimeInfo *iface, DWORD *pdwStartupFlags, LPWSTR pwzHostConfigFile, DWORD *pcchHostConfigFile)
Definition: metahost.c:662
static void CDECL mono_shutdown_callback_fn(MonoProfiler *prof)
Definition: metahost.c:393
MonoDomain * get_root_domain(void)
Definition: metahost.c:366
HRESULT WINAPI CLRMetaHost_GetRuntime(ICLRMetaHost *iface, LPCWSTR pwzVersion, REFIID iid, LPVOID *ppRuntime)
Definition: metahost.c:1149
static ULONG WINAPI CLRMetaHost_AddRef(ICLRMetaHost *iface)
Definition: metahost.c:1066
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
wchar_t *CDECL _wgetenv(const wchar_t *name)
Definition: environ.c:254
char *CDECL getenv(const char *name)
Definition: environ.c:227
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:518
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3286
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
method
Definition: dragdrop.c:54
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT assembly_release(ASSEMBLY *assembly)
Definition: assembly.c:694
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
Definition: assembly.c:865
HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
Definition: assembly.c:641
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum func
Definition: glext.h:6028
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLuint pathA
Definition: glext.h:11719
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
void(__stdcall * RuntimeLoadedCallbackFnPtr)(ICLRRuntimeInfo *pRuntimeInfo, CallbackThreadSetFnPtr pfnCallbackThreadSet, CallbackThreadUnsetFnPtr pfnCallbackThreadUnset)
Definition: metahost.idl:112
METAHOST_POLICY_FLAGS
Definition: metahost.idl:29
@ METAHOST_POLICY_USE_PROCESS_IMAGE_PATH
Definition: metahost.idl:34
@ METAHOST_POLICY_APPLY_UPGRADE_POLICY
Definition: metahost.idl:31
BOOL legacy
Definition: mkisofs.c:131
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memchr(s, c, n)
Definition: mkisofs.h:875
char string[160]
Definition: util.h:11
static const WCHAR filenameW[]
Definition: amstream.c:41
static IPrintDialogCallback callback
Definition: printdlg.c:326
@ RUNTIME_INFO_UPGRADE_VERSION
Definition: mscoree.idl:40
void CDECL mono_log_handler_fn(const char *log_domain, const char *log_level, const char *message, INT fatal, void *user_data)
Definition: mscoree_main.c:265
char * WtoA(LPCWSTR wstr)
Definition: mscoree_main.c:63
void CDECL mono_print_handler_fn(const char *string, INT is_stdout)
Definition: mscoree_main.c:225
HRESULT WINAPI LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll)
Definition: mscoree_main.c:464
void(* MonoLogCallback)(const char *log_domain, const char *log_level, const char *message, INT fatal, void *user_data)
struct _MonoObject MonoObject
struct _MonoThread MonoThread
MonoAssembly *(CDECL * WineMonoAssemblyPreLoadFunc)(MonoAssemblyName *aname, char **assemblies_path, int *flags, void *user_data)
void(CDECL * MonoProfileFunc)(MonoProfiler *prof)
#define WINE_PRELOAD_SET_GAC
#define WINE_PRELOAD_SKIP_PRIVATE_PATH
MonoAssembly *(CDECL * MonoAssemblyPreLoadFunc)(MonoAssemblyName *aname, char **assemblies_path, void *user_data)
struct _MonoProfiler MonoProfiler
#define WINE_MONO_VERSION
void(CDECL * MonoPrintCallback)(const char *string, INT is_stdout)
struct _MonoString MonoString
struct _MonoMethod MonoMethod
struct _MonoAssemblyName MonoAssemblyName
struct _MonoAssembly MonoAssembly
struct _MonoImage MonoImage
MonoAotMode
@ MONO_AOT_MODE_NONE
@ MONO_AOT_MODE_INTERP_ONLY
struct _MonoType MonoType
MonoImageOpenStatus
struct _MonoDomain MonoDomain
#define WINE_PRELOAD_SKIP_GAC
struct _MonoClass MonoClass
unsigned int UINT
Definition: ndis.h:50
#define KEY_READ
Definition: nt_native.h:1026
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
const GUID IID_IEnumUnknown
#define PathAppendW
Definition: pathcch.h:310
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#define CP_UTF8
Definition: nls.h:20
wcscat
wcscpy
strcpy
Definition: string.h:131
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define memset(x, y, z)
Definition: compat.h:39
#define major(rdev)
Definition: propsheet.cpp:928
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
ICLRMetaHostPolicy ICLRMetaHostPolicy_iface
Definition: metahost.c:1288
ICLRMetaHost ICLRMetaHost_iface
Definition: metahost.c:71
RuntimeLoadedCallbackFnPtr callback
Definition: metahost.c:73
IEnumUnknown IEnumUnknown_iface
Definition: metahost.c:893
Definition: http.c:7252
Definition: cookie.c:42
Definition: txthost.c:37
Definition: copy.c:22
Definition: name.c:39
Definition: metahost.c:1417
DWORD flags
Definition: metahost.c:1419
struct list entry
Definition: metahost.c:1420
char * name
Definition: metahost.c:1418
struct list supported_runtimes
Definition: send.c:48
Definition: stat.h:66
Definition: ps.c:97
#define LIST_INIT(head)
Definition: queue.h:197
#define DWORD_PTR
Definition: treelist.c:76
int32_t INT32
Definition: typedefs.h:58
unsigned char * LPBYTE
Definition: typedefs.h:53
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
RTL_RUN_ONCE INIT_ONCE
Definition: winbase.h:3680
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:591
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:3437
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RRF_RT_REG_SZ
Definition: winreg.h:58
#define snprintf
Definition: wintirpc.h:48
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182