3 * Copyright 2008 Alistair Leslie-Hughes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
37 #include "wine/list.h"
38 #include "mscoree_private.h"
40 #include "wine/debug.h"
41 #include "wine/unicode.h"
43 WINE_DEFAULT_DEBUG_CHANNEL( mscoree
);
47 DEFINE_GUID(IID__AppDomain
, 0x05f696dc,0x2b29,0x3663,0xad,0x8b,0xc4,0x38,0x9c,0xf2,0xa7,0x13);
55 static HRESULT
RuntimeHost_AddDomain(RuntimeHost
*This
, MonoDomain
**result
)
57 struct DomainEntry
*entry
;
61 EnterCriticalSection(&This
->lock
);
63 entry
= HeapAlloc(GetProcessHeap(), 0, sizeof(*entry
));
70 mscorlib_path
= WtoA(This
->version
->mscorlib_path
);
73 HeapFree(GetProcessHeap(), 0, entry
);
78 entry
->domain
= This
->mono
->mono_jit_init(mscorlib_path
);
80 HeapFree(GetProcessHeap(), 0, mscorlib_path
);
84 HeapFree(GetProcessHeap(), 0, entry
);
89 This
->mono
->is_started
= TRUE
;
91 list_add_tail(&This
->domains
, &entry
->entry
);
93 *result
= entry
->domain
;
96 LeaveCriticalSection(&This
->lock
);
101 static HRESULT
RuntimeHost_GetDefaultDomain(RuntimeHost
*This
, MonoDomain
**result
)
105 EnterCriticalSection(&This
->lock
);
107 if (This
->default_domain
) goto end
;
109 res
= RuntimeHost_AddDomain(This
, &This
->default_domain
);
112 *result
= This
->default_domain
;
114 LeaveCriticalSection(&This
->lock
);
119 static void RuntimeHost_DeleteDomain(RuntimeHost
*This
, MonoDomain
*domain
)
121 struct DomainEntry
*entry
;
123 EnterCriticalSection(&This
->lock
);
125 LIST_FOR_EACH_ENTRY(entry
, &This
->domains
, struct DomainEntry
, entry
)
127 if (entry
->domain
== domain
)
129 list_remove(&entry
->entry
);
130 if (This
->default_domain
== domain
)
131 This
->default_domain
= NULL
;
132 HeapFree(GetProcessHeap(), 0, entry
);
137 LeaveCriticalSection(&This
->lock
);
140 static HRESULT
RuntimeHost_GetIUnknownForDomain(RuntimeHost
*This
, MonoDomain
*domain
, IUnknown
**punk
)
144 MonoAssembly
*assembly
;
148 MonoObject
*appdomain_object
;
151 This
->mono
->mono_thread_attach(domain
);
153 assembly
= This
->mono
->mono_domain_assembly_open(domain
, "mscorlib");
156 ERR("Cannot load mscorlib\n");
160 image
= This
->mono
->mono_assembly_get_image(assembly
);
163 ERR("Couldn't get assembly image\n");
167 klass
= This
->mono
->mono_class_from_name(image
, "System", "AppDomain");
170 ERR("Couldn't get class from image\n");
174 method
= This
->mono
->mono_class_get_method_from_name(klass
, "get_CurrentDomain", 0);
177 ERR("Couldn't get method from class\n");
182 appdomain_object
= This
->mono
->mono_runtime_invoke(method
, NULL
, args
, NULL
);
183 if (!appdomain_object
)
185 ERR("Couldn't get result pointer\n");
189 hr
= RuntimeHost_GetIUnknownForObject(This
, appdomain_object
, &unk
);
193 hr
= IUnknown_QueryInterface(unk
, &IID__AppDomain
, (void**)punk
);
195 IUnknown_Release(unk
);
201 static inline RuntimeHost
*impl_from_ICLRRuntimeHost( ICLRRuntimeHost
*iface
)
203 return CONTAINING_RECORD(iface
, RuntimeHost
, ICLRRuntimeHost_iface
);
206 static inline RuntimeHost
*impl_from_ICorRuntimeHost( ICorRuntimeHost
*iface
)
208 return CONTAINING_RECORD(iface
, RuntimeHost
, ICorRuntimeHost_iface
);
211 /*** IUnknown methods ***/
212 static HRESULT WINAPI
corruntimehost_QueryInterface(ICorRuntimeHost
* iface
,
216 RuntimeHost
*This
= impl_from_ICorRuntimeHost( iface
);
217 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
219 if ( IsEqualGUID( riid
, &IID_ICorRuntimeHost
) ||
220 IsEqualGUID( riid
, &IID_IUnknown
) )
226 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
227 return E_NOINTERFACE
;
230 ICorRuntimeHost_AddRef( iface
);
235 static ULONG WINAPI
corruntimehost_AddRef(ICorRuntimeHost
* iface
)
237 RuntimeHost
*This
= impl_from_ICorRuntimeHost( iface
);
239 return InterlockedIncrement( &This
->ref
);
242 static ULONG WINAPI
corruntimehost_Release(ICorRuntimeHost
* iface
)
244 RuntimeHost
*This
= impl_from_ICorRuntimeHost( iface
);
247 ref
= InterlockedDecrement( &This
->ref
);
252 /*** ICorRuntimeHost methods ***/
253 static HRESULT WINAPI
corruntimehost_CreateLogicalThreadState(
254 ICorRuntimeHost
* iface
)
256 FIXME("stub %p\n", iface
);
260 static HRESULT WINAPI
corruntimehost_DeleteLogicalThreadState(
261 ICorRuntimeHost
* iface
)
263 FIXME("stub %p\n", iface
);
267 static HRESULT WINAPI
corruntimehost_SwitchInLogicalThreadState(
268 ICorRuntimeHost
* iface
,
271 FIXME("stub %p\n", iface
);
275 static HRESULT WINAPI
corruntimehost_SwitchOutLogicalThreadState(
276 ICorRuntimeHost
* iface
,
279 FIXME("stub %p\n", iface
);
283 static HRESULT WINAPI
corruntimehost_LocksHeldByLogicalThread(
284 ICorRuntimeHost
* iface
,
287 FIXME("stub %p\n", iface
);
291 static HRESULT WINAPI
corruntimehost_MapFile(
292 ICorRuntimeHost
* iface
,
296 FIXME("stub %p\n", iface
);
300 static HRESULT WINAPI
corruntimehost_GetConfiguration(
301 ICorRuntimeHost
* iface
,
302 ICorConfiguration
**pConfiguration
)
304 FIXME("stub %p\n", iface
);
308 static HRESULT WINAPI
corruntimehost_Start(
309 ICorRuntimeHost
* iface
)
311 FIXME("stub %p\n", iface
);
315 static HRESULT WINAPI
corruntimehost_Stop(
316 ICorRuntimeHost
* iface
)
318 FIXME("stub %p\n", iface
);
322 static HRESULT WINAPI
corruntimehost_CreateDomain(
323 ICorRuntimeHost
* iface
,
324 LPCWSTR friendlyName
,
325 IUnknown
*identityArray
,
326 IUnknown
**appDomain
)
328 FIXME("stub %p\n", iface
);
332 static HRESULT WINAPI
corruntimehost_GetDefaultDomain(
333 ICorRuntimeHost
* iface
,
334 IUnknown
**pAppDomain
)
336 RuntimeHost
*This
= impl_from_ICorRuntimeHost( iface
);
340 TRACE("(%p)\n", iface
);
342 hr
= RuntimeHost_GetDefaultDomain(This
, &domain
);
346 hr
= RuntimeHost_GetIUnknownForDomain(This
, domain
, pAppDomain
);
352 static HRESULT WINAPI
corruntimehost_EnumDomains(
353 ICorRuntimeHost
* iface
,
356 FIXME("stub %p\n", iface
);
360 static HRESULT WINAPI
corruntimehost_NextDomain(
361 ICorRuntimeHost
* iface
,
363 IUnknown
**appDomain
)
365 FIXME("stub %p\n", iface
);
369 static HRESULT WINAPI
corruntimehost_CloseEnum(
370 ICorRuntimeHost
* iface
,
373 FIXME("stub %p\n", iface
);
377 static HRESULT WINAPI
corruntimehost_CreateDomainEx(
378 ICorRuntimeHost
* iface
,
379 LPCWSTR friendlyName
,
382 IUnknown
**appDomain
)
384 FIXME("stub %p\n", iface
);
388 static HRESULT WINAPI
corruntimehost_CreateDomainSetup(
389 ICorRuntimeHost
* iface
,
390 IUnknown
**appDomainSetup
)
392 FIXME("stub %p\n", iface
);
396 static HRESULT WINAPI
corruntimehost_CreateEvidence(
397 ICorRuntimeHost
* iface
,
400 FIXME("stub %p\n", iface
);
404 static HRESULT WINAPI
corruntimehost_UnloadDomain(
405 ICorRuntimeHost
* iface
,
408 FIXME("stub %p\n", iface
);
412 static HRESULT WINAPI
corruntimehost_CurrentDomain(
413 ICorRuntimeHost
* iface
,
414 IUnknown
**appDomain
)
416 FIXME("stub %p\n", iface
);
420 static const struct ICorRuntimeHostVtbl corruntimehost_vtbl
=
422 corruntimehost_QueryInterface
,
423 corruntimehost_AddRef
,
424 corruntimehost_Release
,
425 corruntimehost_CreateLogicalThreadState
,
426 corruntimehost_DeleteLogicalThreadState
,
427 corruntimehost_SwitchInLogicalThreadState
,
428 corruntimehost_SwitchOutLogicalThreadState
,
429 corruntimehost_LocksHeldByLogicalThread
,
430 corruntimehost_MapFile
,
431 corruntimehost_GetConfiguration
,
432 corruntimehost_Start
,
434 corruntimehost_CreateDomain
,
435 corruntimehost_GetDefaultDomain
,
436 corruntimehost_EnumDomains
,
437 corruntimehost_NextDomain
,
438 corruntimehost_CloseEnum
,
439 corruntimehost_CreateDomainEx
,
440 corruntimehost_CreateDomainSetup
,
441 corruntimehost_CreateEvidence
,
442 corruntimehost_UnloadDomain
,
443 corruntimehost_CurrentDomain
446 static HRESULT WINAPI
CLRRuntimeHost_QueryInterface(ICLRRuntimeHost
* iface
,
450 RuntimeHost
*This
= impl_from_ICLRRuntimeHost( iface
);
451 TRACE("%p %s %p\n", This
, debugstr_guid(riid
), ppvObject
);
453 if ( IsEqualGUID( riid
, &IID_ICLRRuntimeHost
) ||
454 IsEqualGUID( riid
, &IID_IUnknown
) )
460 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
461 return E_NOINTERFACE
;
464 ICLRRuntimeHost_AddRef( iface
);
469 static ULONG WINAPI
CLRRuntimeHost_AddRef(ICLRRuntimeHost
* iface
)
471 RuntimeHost
*This
= impl_from_ICLRRuntimeHost( iface
);
472 return ICorRuntimeHost_AddRef(&This
->ICorRuntimeHost_iface
);
475 static ULONG WINAPI
CLRRuntimeHost_Release(ICLRRuntimeHost
* iface
)
477 RuntimeHost
*This
= impl_from_ICLRRuntimeHost( iface
);
478 return ICorRuntimeHost_Release(&This
->ICorRuntimeHost_iface
);
481 static HRESULT WINAPI
CLRRuntimeHost_Start(ICLRRuntimeHost
* iface
)
483 FIXME("(%p)\n", iface
);
487 static HRESULT WINAPI
CLRRuntimeHost_Stop(ICLRRuntimeHost
* iface
)
489 FIXME("(%p)\n", iface
);
493 static HRESULT WINAPI
CLRRuntimeHost_SetHostControl(ICLRRuntimeHost
* iface
,
494 IHostControl
*pHostControl
)
496 FIXME("(%p,%p)\n", iface
, pHostControl
);
500 static HRESULT WINAPI
CLRRuntimeHost_GetCLRControl(ICLRRuntimeHost
* iface
,
501 ICLRControl
**pCLRControl
)
503 FIXME("(%p,%p)\n", iface
, pCLRControl
);
507 static HRESULT WINAPI
CLRRuntimeHost_UnloadAppDomain(ICLRRuntimeHost
* iface
,
508 DWORD dwAppDomainId
, BOOL fWaitUntilDone
)
510 FIXME("(%p,%u,%i)\n", iface
, dwAppDomainId
, fWaitUntilDone
);
514 static HRESULT WINAPI
CLRRuntimeHost_ExecuteInAppDomain(ICLRRuntimeHost
* iface
,
515 DWORD dwAppDomainId
, FExecuteInAppDomainCallback pCallback
, void *cookie
)
517 FIXME("(%p,%u,%p,%p)\n", iface
, dwAppDomainId
, pCallback
, cookie
);
521 static HRESULT WINAPI
CLRRuntimeHost_GetCurrentAppDomainId(ICLRRuntimeHost
* iface
,
522 DWORD
*pdwAppDomainId
)
524 FIXME("(%p,%p)\n", iface
, pdwAppDomainId
);
528 static HRESULT WINAPI
CLRRuntimeHost_ExecuteApplication(ICLRRuntimeHost
* iface
,
529 LPCWSTR pwzAppFullName
, DWORD dwManifestPaths
, LPCWSTR
*ppwzManifestPaths
,
530 DWORD dwActivationData
, LPCWSTR
*ppwzActivationData
, int *pReturnValue
)
532 FIXME("(%p,%s,%u,%u)\n", iface
, debugstr_w(pwzAppFullName
), dwManifestPaths
, dwActivationData
);
536 static HRESULT WINAPI
CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost
* iface
,
537 LPCWSTR pwzAssemblyPath
, LPCWSTR pwzTypeName
, LPCWSTR pwzMethodName
,
538 LPCWSTR pwzArgument
, DWORD
*pReturnValue
)
540 RuntimeHost
*This
= impl_from_ICLRRuntimeHost( iface
);
543 MonoAssembly
*assembly
;
550 char *filenameA
= NULL
, *classA
= NULL
, *methodA
= NULL
;
551 char *argsA
= NULL
, *ns
;
553 TRACE("(%p,%s,%s,%s,%s)\n", iface
, debugstr_w(pwzAssemblyPath
),
554 debugstr_w(pwzTypeName
), debugstr_w(pwzMethodName
), debugstr_w(pwzArgument
));
556 hr
= RuntimeHost_GetDefaultDomain(This
, &domain
);
559 ERR("Couldn't get Default Domain\n");
565 This
->mono
->mono_thread_attach(domain
);
567 filenameA
= WtoA(pwzAssemblyPath
);
568 assembly
= This
->mono
->mono_domain_assembly_open(domain
, filenameA
);
571 ERR("Cannot open assembly %s\n", filenameA
);
575 image
= This
->mono
->mono_assembly_get_image(assembly
);
578 ERR("Couldn't get assembly image\n");
582 classA
= WtoA(pwzTypeName
);
583 ns
= strrchr(classA
, '.');
585 klass
= This
->mono
->mono_class_from_name(image
, classA
, ns
+1);
588 ERR("Couldn't get class from image\n");
592 methodA
= WtoA(pwzMethodName
);
593 method
= This
->mono
->mono_class_get_method_from_name(klass
, methodA
, 1);
596 ERR("Couldn't get method from class\n");
600 /* The .NET function we are calling has the following declaration
601 * public static int functionName(String param)
603 argsA
= WtoA(pwzArgument
);
604 str
= This
->mono
->mono_string_new(domain
, argsA
);
607 result
= This
->mono
->mono_runtime_invoke(method
, NULL
, args
, NULL
);
609 ERR("Couldn't get result pointer\n");
612 *pReturnValue
= *(DWORD
*)This
->mono
->mono_object_unbox(result
);
617 HeapFree(GetProcessHeap(), 0, filenameA
);
618 HeapFree(GetProcessHeap(), 0, classA
);
619 HeapFree(GetProcessHeap(), 0, argsA
);
620 HeapFree(GetProcessHeap(), 0, methodA
);
625 static const struct ICLRRuntimeHostVtbl CLRHostVtbl
=
627 CLRRuntimeHost_QueryInterface
,
628 CLRRuntimeHost_AddRef
,
629 CLRRuntimeHost_Release
,
630 CLRRuntimeHost_Start
,
632 CLRRuntimeHost_SetHostControl
,
633 CLRRuntimeHost_GetCLRControl
,
634 CLRRuntimeHost_UnloadAppDomain
,
635 CLRRuntimeHost_ExecuteInAppDomain
,
636 CLRRuntimeHost_GetCurrentAppDomainId
,
637 CLRRuntimeHost_ExecuteApplication
,
638 CLRRuntimeHost_ExecuteInDefaultAppDomain
641 /* Create an instance of a type given its name, by calling its constructor with
642 * no arguments. Note that result MUST be in the stack, or the garbage
643 * collector may free it prematurely. */
644 HRESULT
RuntimeHost_CreateManagedInstance(RuntimeHost
*This
, LPCWSTR name
,
645 MonoDomain
*domain
, MonoObject
**result
)
654 hr
= RuntimeHost_GetDefaultDomain(This
, &domain
);
665 This
->mono
->mono_thread_attach(domain
);
667 type
= This
->mono
->mono_reflection_type_from_name(nameA
, NULL
);
670 ERR("Cannot find type %s\n", debugstr_w(name
));
677 klass
= This
->mono
->mono_class_from_mono_type(type
);
680 ERR("Cannot convert type %s to a class\n", debugstr_w(name
));
687 obj
= This
->mono
->mono_object_new(domain
, klass
);
690 ERR("Cannot allocate object of type %s\n", debugstr_w(name
));
697 /* FIXME: Detect exceptions from the constructor? */
698 This
->mono
->mono_runtime_object_init(obj
);
702 HeapFree(GetProcessHeap(), 0, nameA
);
707 /* Get an IUnknown pointer for a Mono object.
709 * This is just a "light" wrapper around
710 * System.Runtime.InteropServices.Marshal:GetIUnknownForObject
712 * NOTE: The IUnknown* is created with a reference to the object.
713 * Until they have a reference, objects must be in the stack to prevent the
714 * garbage collector from freeing them.
716 * mono_thread_attach must have already been called for this thread. */
717 HRESULT
RuntimeHost_GetIUnknownForObject(RuntimeHost
*This
, MonoObject
*obj
,
721 MonoAssembly
*assembly
;
728 domain
= This
->mono
->mono_object_get_domain(obj
);
730 assembly
= This
->mono
->mono_domain_assembly_open(domain
, "mscorlib");
733 ERR("Cannot load mscorlib\n");
737 image
= This
->mono
->mono_assembly_get_image(assembly
);
740 ERR("Couldn't get assembly image\n");
744 klass
= This
->mono
->mono_class_from_name(image
, "System.Runtime.InteropServices", "Marshal");
747 ERR("Couldn't get class from image\n");
751 method
= This
->mono
->mono_class_get_method_from_name(klass
, "GetIUnknownForObject", 1);
754 ERR("Couldn't get method from class\n");
760 result
= This
->mono
->mono_runtime_invoke(method
, NULL
, args
, NULL
);
763 ERR("Couldn't get result pointer\n");
767 *ppUnk
= *(IUnknown
**)This
->mono
->mono_object_unbox(result
);
770 ERR("GetIUnknownForObject returned 0\n");
777 static void get_utf8_args(int *argc
, char ***argv
)
783 argvw
= CommandLineToArgvW(GetCommandLineW(), argc
);
785 for (i
=0; i
<*argc
; i
++)
787 size
+= sizeof(char*);
788 size
+= WideCharToMultiByte(CP_UTF8
, 0, argvw
[i
], -1, NULL
, 0, NULL
, NULL
);
790 size
+= sizeof(char*);
792 *argv
= HeapAlloc(GetProcessHeap(), 0, size
);
793 current_arg
= (char*)(*argv
+ *argc
+ 1);
795 for (i
=0; i
<*argc
; i
++)
797 (*argv
)[i
] = current_arg
;
798 current_arg
+= WideCharToMultiByte(CP_UTF8
, 0, argvw
[i
], -1, current_arg
, size
, NULL
, NULL
);
801 (*argv
)[*argc
] = NULL
;
803 HeapFree(GetProcessHeap(), 0, argvw
);
806 static void FixupVTable(HMODULE hmodule
)
810 VTableFixup
*vtable_fixups
;
811 ULONG vtable_fixup_count
;
813 hr
= assembly_from_hmodule(&assembly
, hmodule
);
816 hr
= assembly_get_vtable_fixups(assembly
, &vtable_fixups
, &vtable_fixup_count
);
817 if (vtable_fixup_count
)
818 FIXME("vtable fixups are not implemented; expect a crash\n");
820 assembly_release(assembly
);
823 ERR("failed to read CLR headers, hr=%x\n", hr
);
826 __int32 WINAPI
_CorExeMain(void)
833 MonoImageOpenStatus status
;
834 MonoAssembly
*assembly
=NULL
;
835 WCHAR filename
[MAX_PATH
];
837 ICLRRuntimeInfo
*info
;
842 get_utf8_args(&argc
, &argv
);
844 GetModuleFileNameW(NULL
, filename
, MAX_PATH
);
846 TRACE("%s", debugstr_w(filename
));
847 for (i
=0; i
<argc
; i
++)
848 TRACE(" %s", debugstr_a(argv
[i
]));
851 filenameA
= WtoA(filename
);
855 FixupVTable(GetModuleHandleW(NULL
));
857 hr
= get_runtime_info(filename
, NULL
, NULL
, 0, 0, FALSE
, &info
);
861 hr
= ICLRRuntimeInfo_GetRuntimeHost(info
, &host
);
864 hr
= RuntimeHost_GetDefaultDomain(host
, &domain
);
868 image
= host
->mono
->mono_image_open_from_module_handle(GetModuleHandleW(NULL
),
869 filenameA
, 1, &status
);
872 assembly
= host
->mono
->mono_assembly_load_from(image
, filenameA
, &status
);
876 exit_code
= host
->mono
->mono_jit_exec(domain
, assembly
, argc
, argv
);
880 ERR("couldn't load %s, status=%d\n", debugstr_w(filename
), status
);
884 RuntimeHost_DeleteDomain(host
, domain
);
889 ICLRRuntimeInfo_Release(info
);
894 HeapFree(GetProcessHeap(), 0, argv
);
896 unload_all_runtimes();
901 BOOL WINAPI
_CorDllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
903 TRACE("(%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
907 case DLL_PROCESS_ATTACH
:
908 DisableThreadLibraryCalls(hinstDLL
);
909 FixupVTable(hinstDLL
);
911 case DLL_PROCESS_DETACH
:
917 HRESULT
RuntimeHost_Construct(const CLRRuntimeInfo
*runtime_version
,
918 loaded_mono
*loaded_mono
, RuntimeHost
** result
)
922 This
= HeapAlloc( GetProcessHeap(), 0, sizeof *This
);
924 return E_OUTOFMEMORY
;
926 This
->ICorRuntimeHost_iface
.lpVtbl
= &corruntimehost_vtbl
;
927 This
->ICLRRuntimeHost_iface
.lpVtbl
= &CLRHostVtbl
;
930 This
->version
= runtime_version
;
931 This
->mono
= loaded_mono
;
932 list_init(&This
->domains
);
933 This
->default_domain
= NULL
;
934 InitializeCriticalSection(&This
->lock
);
935 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": RuntimeHost.lock");
942 HRESULT
RuntimeHost_GetInterface(RuntimeHost
*This
, REFCLSID clsid
, REFIID riid
, void **ppv
)
947 if (IsEqualGUID(clsid
, &CLSID_CorRuntimeHost
))
949 unk
= (IUnknown
*)&This
->ICorRuntimeHost_iface
;
950 IUnknown_AddRef(unk
);
952 else if (IsEqualGUID(clsid
, &CLSID_CLRRuntimeHost
))
954 unk
= (IUnknown
*)&This
->ICLRRuntimeHost_iface
;
955 IUnknown_AddRef(unk
);
957 else if (IsEqualGUID(clsid
, &CLSID_CorMetaDataDispenser
) ||
958 IsEqualGUID(clsid
, &CLSID_CorMetaDataDispenserRuntime
))
960 hr
= MetaDataDispenser_CreateInstance(&unk
);
964 else if (IsEqualGUID(clsid
, &CLSID_CLRDebuggingLegacy
))
966 hr
= CorDebug_Create(&This
->ICLRRuntimeHost_iface
, &unk
);
975 hr
= IUnknown_QueryInterface(unk
, riid
, ppv
);
977 IUnknown_Release(unk
);
982 FIXME("not implemented for class %s\n", debugstr_guid(clsid
));
984 return CLASS_E_CLASSNOTAVAILABLE
;
987 HRESULT
RuntimeHost_Destroy(RuntimeHost
*This
)
989 struct DomainEntry
*cursor
, *cursor2
;
991 This
->lock
.DebugInfo
->Spare
[0] = 0;
992 DeleteCriticalSection(&This
->lock
);
994 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->domains
, struct DomainEntry
, entry
)
996 list_remove(&cursor
->entry
);
997 HeapFree(GetProcessHeap(), 0, cursor
);
1000 HeapFree( GetProcessHeap(), 0, This
);
1004 #define CHARS_IN_GUID 39
1005 #define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
1007 HRESULT
create_monodata(REFIID riid
, LPVOID
*ppObj
)
1009 static const WCHAR wszCodebase
[] = {'C','o','d','e','B','a','s','e',0};
1010 static const WCHAR wszClass
[] = {'C','l','a','s','s',0};
1011 static const WCHAR wszFileSlash
[] = {'f','i','l','e',':','/','/','/',0};
1012 static const WCHAR wszCLSIDSlash
[] = {'C','L','S','I','D','\\',0};
1013 static const WCHAR wszInprocServer32
[] = {'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
1014 WCHAR path
[CHARS_IN_GUID
+ ARRAYSIZE(wszCLSIDSlash
) + ARRAYSIZE(wszInprocServer32
) - 1];
1016 MonoAssembly
*assembly
;
1017 ICLRRuntimeInfo
*info
;
1023 WCHAR codebase
[MAX_PATH
+ 8];
1024 WCHAR classname
[350];
1025 WCHAR filename
[MAX_PATH
];
1027 DWORD dwBufLen
= 350;
1029 lstrcpyW(path
, wszCLSIDSlash
);
1030 StringFromGUID2(riid
, path
+ lstrlenW(wszCLSIDSlash
), CHARS_IN_GUID
);
1031 lstrcatW(path
, wszInprocServer32
);
1033 TRACE("Registry key: %s\n", debugstr_w(path
));
1035 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, path
, 0, KEY_READ
, &key
);
1036 if (res
== ERROR_FILE_NOT_FOUND
)
1037 return CLASS_E_CLASSNOTAVAILABLE
;
1039 res
= RegGetValueW( key
, NULL
, wszClass
, RRF_RT_REG_SZ
, NULL
, classname
, &dwBufLen
);
1040 if(res
!= ERROR_SUCCESS
)
1042 WARN("Class value cannot be found.\n");
1043 hr
= CLASS_E_CLASSNOTAVAILABLE
;
1047 TRACE("classname (%s)\n", debugstr_w(classname
));
1049 dwBufLen
= MAX_PATH
+ 8;
1050 res
= RegGetValueW( key
, NULL
, wszCodebase
, RRF_RT_REG_SZ
, NULL
, codebase
, &dwBufLen
);
1051 if(res
!= ERROR_SUCCESS
)
1053 WARN("CodeBase value cannot be found.\n");
1054 hr
= CLASS_E_CLASSNOTAVAILABLE
;
1058 /* Strip file:/// */
1059 if(strncmpW(codebase
, wszFileSlash
, strlenW(wszFileSlash
)) == 0)
1060 offset
= strlenW(wszFileSlash
);
1062 strcpyW(filename
, codebase
+ offset
);
1064 TRACE("codebase (%s)\n", debugstr_w(filename
));
1069 hr
= get_runtime_info(filename
, NULL
, NULL
, 0, 0, FALSE
, &info
);
1072 hr
= ICLRRuntimeInfo_GetRuntimeHost(info
, &host
);
1075 hr
= RuntimeHost_GetDefaultDomain(host
, &domain
);
1082 IUnknown
*unk
= NULL
;
1083 char *filenameA
, *ns
;
1086 hr
= CLASS_E_CLASSNOTAVAILABLE
;
1088 host
->mono
->mono_thread_attach(domain
);
1090 filenameA
= WtoA(filename
);
1091 assembly
= host
->mono
->mono_domain_assembly_open(domain
, filenameA
);
1092 HeapFree(GetProcessHeap(), 0, filenameA
);
1095 ERR("Cannot open assembly %s\n", filenameA
);
1099 image
= host
->mono
->mono_assembly_get_image(assembly
);
1102 ERR("Couldn't get assembly image\n");
1106 classA
= WtoA(classname
);
1107 ns
= strrchr(classA
, '.');
1110 klass
= host
->mono
->mono_class_from_name(image
, classA
, ns
+1);
1111 HeapFree(GetProcessHeap(), 0, classA
);
1114 ERR("Couldn't get class from image\n");
1119 * Use the default constructor for the .NET class.
1121 result
= host
->mono
->mono_object_new(domain
, klass
);
1122 host
->mono
->mono_runtime_object_init(result
);
1124 hr
= RuntimeHost_GetIUnknownForObject(host
, result
, &unk
);
1127 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, ppObj
);
1129 IUnknown_Release(unk
);
1132 hr
= CLASS_E_CLASSNOTAVAILABLE
;
1135 hr
= CLASS_E_CLASSNOTAVAILABLE
;
1138 hr
= CLASS_E_CLASSNOTAVAILABLE
;
1142 ICLRRuntimeInfo_Release(info
);