Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencorruntimehost.c
Go to the documentation of this file.
00001 /* 00002 * 00003 * Copyright 2008 Alistair Leslie-Hughes 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 #define COBJMACROS 00021 00022 #include <stdarg.h> 00023 00024 #include "windef.h" 00025 #include "winbase.h" 00026 #include "winuser.h" 00027 #include "winnls.h" 00028 #include "winreg.h" 00029 #include "ole2.h" 00030 #include "shellapi.h" 00031 00032 #include "cor.h" 00033 #include "mscoree.h" 00034 #include "metahost.h" 00035 #include "corhdr.h" 00036 #include "cordebug.h" 00037 #include "wine/list.h" 00038 #include "mscoree_private.h" 00039 00040 #include "wine/debug.h" 00041 00042 WINE_DEFAULT_DEBUG_CHANNEL( mscoree ); 00043 00044 #include "initguid.h" 00045 00046 DEFINE_GUID(IID__AppDomain, 0x05f696dc,0x2b29,0x3663,0xad,0x8b,0xc4,0x38,0x9c,0xf2,0xa7,0x13); 00047 00048 struct DomainEntry 00049 { 00050 struct list entry; 00051 MonoDomain *domain; 00052 }; 00053 00054 static HRESULT RuntimeHost_AddDomain(RuntimeHost *This, MonoDomain **result) 00055 { 00056 struct DomainEntry *entry; 00057 char *mscorlib_path; 00058 HRESULT res=S_OK; 00059 00060 EnterCriticalSection(&This->lock); 00061 00062 entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); 00063 if (!entry) 00064 { 00065 res = E_OUTOFMEMORY; 00066 goto end; 00067 } 00068 00069 mscorlib_path = WtoA(This->version->mscorlib_path); 00070 if (!mscorlib_path) 00071 { 00072 HeapFree(GetProcessHeap(), 0, entry); 00073 res = E_OUTOFMEMORY; 00074 goto end; 00075 } 00076 00077 entry->domain = This->mono->mono_jit_init(mscorlib_path); 00078 00079 HeapFree(GetProcessHeap(), 0, mscorlib_path); 00080 00081 if (!entry->domain) 00082 { 00083 HeapFree(GetProcessHeap(), 0, entry); 00084 res = E_FAIL; 00085 goto end; 00086 } 00087 00088 This->mono->is_started = TRUE; 00089 00090 list_add_tail(&This->domains, &entry->entry); 00091 00092 *result = entry->domain; 00093 00094 end: 00095 LeaveCriticalSection(&This->lock); 00096 00097 return res; 00098 } 00099 00100 static HRESULT RuntimeHost_GetDefaultDomain(RuntimeHost *This, MonoDomain **result) 00101 { 00102 HRESULT res=S_OK; 00103 00104 EnterCriticalSection(&This->lock); 00105 00106 if (This->default_domain) goto end; 00107 00108 res = RuntimeHost_AddDomain(This, &This->default_domain); 00109 00110 end: 00111 *result = This->default_domain; 00112 00113 LeaveCriticalSection(&This->lock); 00114 00115 return res; 00116 } 00117 00118 static void RuntimeHost_DeleteDomain(RuntimeHost *This, MonoDomain *domain) 00119 { 00120 struct DomainEntry *entry; 00121 00122 EnterCriticalSection(&This->lock); 00123 00124 LIST_FOR_EACH_ENTRY(entry, &This->domains, struct DomainEntry, entry) 00125 { 00126 if (entry->domain == domain) 00127 { 00128 list_remove(&entry->entry); 00129 if (This->default_domain == domain) 00130 This->default_domain = NULL; 00131 HeapFree(GetProcessHeap(), 0, entry); 00132 break; 00133 } 00134 } 00135 00136 LeaveCriticalSection(&This->lock); 00137 } 00138 00139 static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *domain, IUnknown **punk) 00140 { 00141 HRESULT hr; 00142 void *args[1]; 00143 MonoAssembly *assembly; 00144 MonoImage *image; 00145 MonoClass *klass; 00146 MonoMethod *method; 00147 MonoObject *appdomain_object; 00148 IUnknown *unk; 00149 00150 assembly = This->mono->mono_domain_assembly_open(domain, "mscorlib"); 00151 if (!assembly) 00152 { 00153 ERR("Cannot load mscorlib\n"); 00154 return E_FAIL; 00155 } 00156 00157 image = This->mono->mono_assembly_get_image(assembly); 00158 if (!image) 00159 { 00160 ERR("Couldn't get assembly image\n"); 00161 return E_FAIL; 00162 } 00163 00164 klass = This->mono->mono_class_from_name(image, "System", "AppDomain"); 00165 if (!klass) 00166 { 00167 ERR("Couldn't get class from image\n"); 00168 return E_FAIL; 00169 } 00170 00171 method = This->mono->mono_class_get_method_from_name(klass, "get_CurrentDomain", 0); 00172 if (!method) 00173 { 00174 ERR("Couldn't get method from class\n"); 00175 return E_FAIL; 00176 } 00177 00178 args[0] = NULL; 00179 appdomain_object = This->mono->mono_runtime_invoke(method, NULL, args, NULL); 00180 if (!appdomain_object) 00181 { 00182 ERR("Couldn't get result pointer\n"); 00183 return E_FAIL; 00184 } 00185 00186 hr = RuntimeHost_GetIUnknownForObject(This, appdomain_object, &unk); 00187 00188 if (SUCCEEDED(hr)) 00189 { 00190 hr = IUnknown_QueryInterface(unk, &IID__AppDomain, (void**)punk); 00191 00192 IUnknown_Release(unk); 00193 } 00194 00195 return hr; 00196 } 00197 00198 static inline RuntimeHost *impl_from_ICLRRuntimeHost( ICLRRuntimeHost *iface ) 00199 { 00200 return CONTAINING_RECORD(iface, RuntimeHost, ICLRRuntimeHost_iface); 00201 } 00202 00203 static inline RuntimeHost *impl_from_ICorRuntimeHost( ICorRuntimeHost *iface ) 00204 { 00205 return CONTAINING_RECORD(iface, RuntimeHost, ICorRuntimeHost_iface); 00206 } 00207 00208 /*** IUnknown methods ***/ 00209 static HRESULT WINAPI corruntimehost_QueryInterface(ICorRuntimeHost* iface, 00210 REFIID riid, 00211 void **ppvObject) 00212 { 00213 RuntimeHost *This = impl_from_ICorRuntimeHost( iface ); 00214 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 00215 00216 if ( IsEqualGUID( riid, &IID_ICorRuntimeHost ) || 00217 IsEqualGUID( riid, &IID_IUnknown ) ) 00218 { 00219 *ppvObject = iface; 00220 } 00221 else 00222 { 00223 FIXME("Unsupported interface %s\n", debugstr_guid(riid)); 00224 return E_NOINTERFACE; 00225 } 00226 00227 ICorRuntimeHost_AddRef( iface ); 00228 00229 return S_OK; 00230 } 00231 00232 static ULONG WINAPI corruntimehost_AddRef(ICorRuntimeHost* iface) 00233 { 00234 RuntimeHost *This = impl_from_ICorRuntimeHost( iface ); 00235 00236 return InterlockedIncrement( &This->ref ); 00237 } 00238 00239 static ULONG WINAPI corruntimehost_Release(ICorRuntimeHost* iface) 00240 { 00241 RuntimeHost *This = impl_from_ICorRuntimeHost( iface ); 00242 ULONG ref; 00243 00244 ref = InterlockedDecrement( &This->ref ); 00245 00246 return ref; 00247 } 00248 00249 /*** ICorRuntimeHost methods ***/ 00250 static HRESULT WINAPI corruntimehost_CreateLogicalThreadState( 00251 ICorRuntimeHost* iface) 00252 { 00253 FIXME("stub %p\n", iface); 00254 return E_NOTIMPL; 00255 } 00256 00257 static HRESULT WINAPI corruntimehost_DeleteLogicalThreadState( 00258 ICorRuntimeHost* iface) 00259 { 00260 FIXME("stub %p\n", iface); 00261 return E_NOTIMPL; 00262 } 00263 00264 static HRESULT WINAPI corruntimehost_SwitchInLogicalThreadState( 00265 ICorRuntimeHost* iface, 00266 DWORD *fiberCookie) 00267 { 00268 FIXME("stub %p\n", iface); 00269 return E_NOTIMPL; 00270 } 00271 00272 static HRESULT WINAPI corruntimehost_SwitchOutLogicalThreadState( 00273 ICorRuntimeHost* iface, 00274 DWORD **fiberCookie) 00275 { 00276 FIXME("stub %p\n", iface); 00277 return E_NOTIMPL; 00278 } 00279 00280 static HRESULT WINAPI corruntimehost_LocksHeldByLogicalThread( 00281 ICorRuntimeHost* iface, 00282 DWORD *pCount) 00283 { 00284 FIXME("stub %p\n", iface); 00285 return E_NOTIMPL; 00286 } 00287 00288 static HRESULT WINAPI corruntimehost_MapFile( 00289 ICorRuntimeHost* iface, 00290 HANDLE hFile, 00291 HMODULE *mapAddress) 00292 { 00293 FIXME("stub %p\n", iface); 00294 return E_NOTIMPL; 00295 } 00296 00297 static HRESULT WINAPI corruntimehost_GetConfiguration( 00298 ICorRuntimeHost* iface, 00299 ICorConfiguration **pConfiguration) 00300 { 00301 FIXME("stub %p\n", iface); 00302 return E_NOTIMPL; 00303 } 00304 00305 static HRESULT WINAPI corruntimehost_Start( 00306 ICorRuntimeHost* iface) 00307 { 00308 FIXME("stub %p\n", iface); 00309 return S_OK; 00310 } 00311 00312 static HRESULT WINAPI corruntimehost_Stop( 00313 ICorRuntimeHost* iface) 00314 { 00315 FIXME("stub %p\n", iface); 00316 return E_NOTIMPL; 00317 } 00318 00319 static HRESULT WINAPI corruntimehost_CreateDomain( 00320 ICorRuntimeHost* iface, 00321 LPCWSTR friendlyName, 00322 IUnknown *identityArray, 00323 IUnknown **appDomain) 00324 { 00325 FIXME("stub %p\n", iface); 00326 return E_NOTIMPL; 00327 } 00328 00329 static HRESULT WINAPI corruntimehost_GetDefaultDomain( 00330 ICorRuntimeHost* iface, 00331 IUnknown **pAppDomain) 00332 { 00333 RuntimeHost *This = impl_from_ICorRuntimeHost( iface ); 00334 HRESULT hr; 00335 MonoDomain *domain; 00336 00337 TRACE("(%p)\n", iface); 00338 00339 hr = RuntimeHost_GetDefaultDomain(This, &domain); 00340 00341 if (SUCCEEDED(hr)) 00342 { 00343 hr = RuntimeHost_GetIUnknownForDomain(This, domain, pAppDomain); 00344 } 00345 00346 return hr; 00347 } 00348 00349 static HRESULT WINAPI corruntimehost_EnumDomains( 00350 ICorRuntimeHost* iface, 00351 HDOMAINENUM *hEnum) 00352 { 00353 FIXME("stub %p\n", iface); 00354 return E_NOTIMPL; 00355 } 00356 00357 static HRESULT WINAPI corruntimehost_NextDomain( 00358 ICorRuntimeHost* iface, 00359 HDOMAINENUM hEnum, 00360 IUnknown **appDomain) 00361 { 00362 FIXME("stub %p\n", iface); 00363 return E_NOTIMPL; 00364 } 00365 00366 static HRESULT WINAPI corruntimehost_CloseEnum( 00367 ICorRuntimeHost* iface, 00368 HDOMAINENUM hEnum) 00369 { 00370 FIXME("stub %p\n", iface); 00371 return E_NOTIMPL; 00372 } 00373 00374 static HRESULT WINAPI corruntimehost_CreateDomainEx( 00375 ICorRuntimeHost* iface, 00376 LPCWSTR friendlyName, 00377 IUnknown *setup, 00378 IUnknown *evidence, 00379 IUnknown **appDomain) 00380 { 00381 FIXME("stub %p\n", iface); 00382 return E_NOTIMPL; 00383 } 00384 00385 static HRESULT WINAPI corruntimehost_CreateDomainSetup( 00386 ICorRuntimeHost* iface, 00387 IUnknown **appDomainSetup) 00388 { 00389 FIXME("stub %p\n", iface); 00390 return E_NOTIMPL; 00391 } 00392 00393 static HRESULT WINAPI corruntimehost_CreateEvidence( 00394 ICorRuntimeHost* iface, 00395 IUnknown **evidence) 00396 { 00397 FIXME("stub %p\n", iface); 00398 return E_NOTIMPL; 00399 } 00400 00401 static HRESULT WINAPI corruntimehost_UnloadDomain( 00402 ICorRuntimeHost* iface, 00403 IUnknown *appDomain) 00404 { 00405 FIXME("stub %p\n", iface); 00406 return E_NOTIMPL; 00407 } 00408 00409 static HRESULT WINAPI corruntimehost_CurrentDomain( 00410 ICorRuntimeHost* iface, 00411 IUnknown **appDomain) 00412 { 00413 FIXME("stub %p\n", iface); 00414 return E_NOTIMPL; 00415 } 00416 00417 static const struct ICorRuntimeHostVtbl corruntimehost_vtbl = 00418 { 00419 corruntimehost_QueryInterface, 00420 corruntimehost_AddRef, 00421 corruntimehost_Release, 00422 corruntimehost_CreateLogicalThreadState, 00423 corruntimehost_DeleteLogicalThreadState, 00424 corruntimehost_SwitchInLogicalThreadState, 00425 corruntimehost_SwitchOutLogicalThreadState, 00426 corruntimehost_LocksHeldByLogicalThread, 00427 corruntimehost_MapFile, 00428 corruntimehost_GetConfiguration, 00429 corruntimehost_Start, 00430 corruntimehost_Stop, 00431 corruntimehost_CreateDomain, 00432 corruntimehost_GetDefaultDomain, 00433 corruntimehost_EnumDomains, 00434 corruntimehost_NextDomain, 00435 corruntimehost_CloseEnum, 00436 corruntimehost_CreateDomainEx, 00437 corruntimehost_CreateDomainSetup, 00438 corruntimehost_CreateEvidence, 00439 corruntimehost_UnloadDomain, 00440 corruntimehost_CurrentDomain 00441 }; 00442 00443 static HRESULT WINAPI CLRRuntimeHost_QueryInterface(ICLRRuntimeHost* iface, 00444 REFIID riid, 00445 void **ppvObject) 00446 { 00447 RuntimeHost *This = impl_from_ICLRRuntimeHost( iface ); 00448 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 00449 00450 if ( IsEqualGUID( riid, &IID_ICLRRuntimeHost ) || 00451 IsEqualGUID( riid, &IID_IUnknown ) ) 00452 { 00453 *ppvObject = iface; 00454 } 00455 else 00456 { 00457 FIXME("Unsupported interface %s\n", debugstr_guid(riid)); 00458 return E_NOINTERFACE; 00459 } 00460 00461 ICLRRuntimeHost_AddRef( iface ); 00462 00463 return S_OK; 00464 } 00465 00466 static ULONG WINAPI CLRRuntimeHost_AddRef(ICLRRuntimeHost* iface) 00467 { 00468 RuntimeHost *This = impl_from_ICLRRuntimeHost( iface ); 00469 return ICorRuntimeHost_AddRef(&This->ICorRuntimeHost_iface); 00470 } 00471 00472 static ULONG WINAPI CLRRuntimeHost_Release(ICLRRuntimeHost* iface) 00473 { 00474 RuntimeHost *This = impl_from_ICLRRuntimeHost( iface ); 00475 return ICorRuntimeHost_Release(&This->ICorRuntimeHost_iface); 00476 } 00477 00478 static HRESULT WINAPI CLRRuntimeHost_Start(ICLRRuntimeHost* iface) 00479 { 00480 FIXME("(%p)\n", iface); 00481 return E_NOTIMPL; 00482 } 00483 00484 static HRESULT WINAPI CLRRuntimeHost_Stop(ICLRRuntimeHost* iface) 00485 { 00486 FIXME("(%p)\n", iface); 00487 return E_NOTIMPL; 00488 } 00489 00490 static HRESULT WINAPI CLRRuntimeHost_SetHostControl(ICLRRuntimeHost* iface, 00491 IHostControl *pHostControl) 00492 { 00493 FIXME("(%p,%p)\n", iface, pHostControl); 00494 return E_NOTIMPL; 00495 } 00496 00497 static HRESULT WINAPI CLRRuntimeHost_GetCLRControl(ICLRRuntimeHost* iface, 00498 ICLRControl **pCLRControl) 00499 { 00500 FIXME("(%p,%p)\n", iface, pCLRControl); 00501 return E_NOTIMPL; 00502 } 00503 00504 static HRESULT WINAPI CLRRuntimeHost_UnloadAppDomain(ICLRRuntimeHost* iface, 00505 DWORD dwAppDomainId, BOOL fWaitUntilDone) 00506 { 00507 FIXME("(%p,%u,%i)\n", iface, dwAppDomainId, fWaitUntilDone); 00508 return E_NOTIMPL; 00509 } 00510 00511 static HRESULT WINAPI CLRRuntimeHost_ExecuteInAppDomain(ICLRRuntimeHost* iface, 00512 DWORD dwAppDomainId, FExecuteInAppDomainCallback pCallback, void *cookie) 00513 { 00514 FIXME("(%p,%u,%p,%p)\n", iface, dwAppDomainId, pCallback, cookie); 00515 return E_NOTIMPL; 00516 } 00517 00518 static HRESULT WINAPI CLRRuntimeHost_GetCurrentAppDomainId(ICLRRuntimeHost* iface, 00519 DWORD *pdwAppDomainId) 00520 { 00521 FIXME("(%p,%p)\n", iface, pdwAppDomainId); 00522 return E_NOTIMPL; 00523 } 00524 00525 static HRESULT WINAPI CLRRuntimeHost_ExecuteApplication(ICLRRuntimeHost* iface, 00526 LPCWSTR pwzAppFullName, DWORD dwManifestPaths, LPCWSTR *ppwzManifestPaths, 00527 DWORD dwActivationData, LPCWSTR *ppwzActivationData, int *pReturnValue) 00528 { 00529 FIXME("(%p,%s,%u,%u)\n", iface, debugstr_w(pwzAppFullName), dwManifestPaths, dwActivationData); 00530 return E_NOTIMPL; 00531 } 00532 00533 static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* iface, 00534 LPCWSTR pwzAssemblyPath, LPCWSTR pwzTypeName, LPCWSTR pwzMethodName, 00535 LPCWSTR pwzArgument, DWORD *pReturnValue) 00536 { 00537 RuntimeHost *This = impl_from_ICLRRuntimeHost( iface ); 00538 HRESULT hr; 00539 MonoDomain *domain; 00540 MonoAssembly *assembly; 00541 MonoImage *image; 00542 MonoClass *klass; 00543 MonoMethod *method; 00544 MonoObject *result; 00545 MonoString *str; 00546 void *args[2]; 00547 char *filenameA = NULL, *classA = NULL, *methodA = NULL; 00548 char *argsA = NULL, *ns; 00549 00550 TRACE("(%p,%s,%s,%s,%s)\n", iface, debugstr_w(pwzAssemblyPath), 00551 debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument)); 00552 00553 hr = RuntimeHost_GetDefaultDomain(This, &domain); 00554 if(hr != S_OK) 00555 { 00556 ERR("Couldn't get Default Domain\n"); 00557 return hr; 00558 } 00559 00560 hr = E_FAIL; 00561 00562 filenameA = WtoA(pwzAssemblyPath); 00563 assembly = This->mono->mono_domain_assembly_open(domain, filenameA); 00564 if (!assembly) 00565 { 00566 ERR("Cannot open assembly %s\n", filenameA); 00567 goto cleanup; 00568 } 00569 00570 image = This->mono->mono_assembly_get_image(assembly); 00571 if (!image) 00572 { 00573 ERR("Couldn't get assembly image\n"); 00574 goto cleanup; 00575 } 00576 00577 classA = WtoA(pwzTypeName); 00578 ns = strrchr(classA, '.'); 00579 *ns = '\0'; 00580 klass = This->mono->mono_class_from_name(image, classA, ns+1); 00581 if (!klass) 00582 { 00583 ERR("Couldn't get class from image\n"); 00584 goto cleanup; 00585 } 00586 00587 methodA = WtoA(pwzMethodName); 00588 method = This->mono->mono_class_get_method_from_name(klass, methodA, 1); 00589 if (!method) 00590 { 00591 ERR("Couldn't get method from class\n"); 00592 goto cleanup; 00593 } 00594 00595 /* The .NET function we are calling has the following declaration 00596 * public static int functionName(String param) 00597 */ 00598 argsA = WtoA(pwzArgument); 00599 str = This->mono->mono_string_new(domain, argsA); 00600 args[0] = str; 00601 args[1] = NULL; 00602 result = This->mono->mono_runtime_invoke(method, NULL, args, NULL); 00603 if (!result) 00604 ERR("Couldn't get result pointer\n"); 00605 else 00606 { 00607 *pReturnValue = *(DWORD*)This->mono->mono_object_unbox(result); 00608 hr = S_OK; 00609 } 00610 00611 cleanup: 00612 if(filenameA) 00613 HeapFree(GetProcessHeap(), 0, filenameA); 00614 if(classA) 00615 HeapFree(GetProcessHeap(), 0, classA); 00616 if(argsA) 00617 HeapFree(GetProcessHeap(), 0, argsA); 00618 if(methodA) 00619 HeapFree(GetProcessHeap(), 0, methodA); 00620 00621 return hr; 00622 } 00623 00624 static const struct ICLRRuntimeHostVtbl CLRHostVtbl = 00625 { 00626 CLRRuntimeHost_QueryInterface, 00627 CLRRuntimeHost_AddRef, 00628 CLRRuntimeHost_Release, 00629 CLRRuntimeHost_Start, 00630 CLRRuntimeHost_Stop, 00631 CLRRuntimeHost_SetHostControl, 00632 CLRRuntimeHost_GetCLRControl, 00633 CLRRuntimeHost_UnloadAppDomain, 00634 CLRRuntimeHost_ExecuteInAppDomain, 00635 CLRRuntimeHost_GetCurrentAppDomainId, 00636 CLRRuntimeHost_ExecuteApplication, 00637 CLRRuntimeHost_ExecuteInDefaultAppDomain 00638 }; 00639 00640 /* Create an instance of a type given its name, by calling its constructor with 00641 * no arguments. Note that result MUST be in the stack, or the garbage 00642 * collector may free it prematurely. */ 00643 HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name, 00644 MonoDomain *domain, MonoObject **result) 00645 { 00646 HRESULT hr=S_OK; 00647 char *nameA=NULL; 00648 MonoType *type; 00649 MonoClass *klass; 00650 MonoObject *obj; 00651 00652 if (!domain) 00653 hr = RuntimeHost_GetDefaultDomain(This, &domain); 00654 00655 if (SUCCEEDED(hr)) 00656 { 00657 nameA = WtoA(name); 00658 if (!nameA) 00659 hr = E_OUTOFMEMORY; 00660 } 00661 00662 if (SUCCEEDED(hr)) 00663 { 00664 type = This->mono->mono_reflection_type_from_name(nameA, NULL); 00665 if (!type) 00666 { 00667 ERR("Cannot find type %s\n", debugstr_w(name)); 00668 hr = E_FAIL; 00669 } 00670 } 00671 00672 if (SUCCEEDED(hr)) 00673 { 00674 klass = This->mono->mono_class_from_mono_type(type); 00675 if (!klass) 00676 { 00677 ERR("Cannot convert type %s to a class\n", debugstr_w(name)); 00678 hr = E_FAIL; 00679 } 00680 } 00681 00682 if (SUCCEEDED(hr)) 00683 { 00684 obj = This->mono->mono_object_new(domain, klass); 00685 if (!obj) 00686 { 00687 ERR("Cannot allocate object of type %s\n", debugstr_w(name)); 00688 hr = E_FAIL; 00689 } 00690 } 00691 00692 if (SUCCEEDED(hr)) 00693 { 00694 /* FIXME: Detect exceptions from the constructor? */ 00695 This->mono->mono_runtime_object_init(obj); 00696 *result = obj; 00697 } 00698 00699 HeapFree(GetProcessHeap(), 0, nameA); 00700 00701 return hr; 00702 } 00703 00704 /* Get an IUnknown pointer for a Mono object. 00705 * 00706 * This is just a "light" wrapper around 00707 * System.Runtime.InteropServices.Marshal:GetIUnknownForObject 00708 * 00709 * NOTE: The IUnknown* is created with a reference to the object. 00710 * Until they have a reference, objects must be in the stack to prevent the 00711 * garbage collector from freeing them. */ 00712 HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj, 00713 IUnknown **ppUnk) 00714 { 00715 MonoDomain *domain; 00716 MonoAssembly *assembly; 00717 MonoImage *image; 00718 MonoClass *klass; 00719 MonoMethod *method; 00720 MonoObject *result; 00721 void *args[2]; 00722 00723 domain = This->mono->mono_object_get_domain(obj); 00724 00725 assembly = This->mono->mono_domain_assembly_open(domain, "mscorlib"); 00726 if (!assembly) 00727 { 00728 ERR("Cannot load mscorlib\n"); 00729 return E_FAIL; 00730 } 00731 00732 image = This->mono->mono_assembly_get_image(assembly); 00733 if (!image) 00734 { 00735 ERR("Couldn't get assembly image\n"); 00736 return E_FAIL; 00737 } 00738 00739 klass = This->mono->mono_class_from_name(image, "System.Runtime.InteropServices", "Marshal"); 00740 if (!klass) 00741 { 00742 ERR("Couldn't get class from image\n"); 00743 return E_FAIL; 00744 } 00745 00746 method = This->mono->mono_class_get_method_from_name(klass, "GetIUnknownForObject", 1); 00747 if (!method) 00748 { 00749 ERR("Couldn't get method from class\n"); 00750 return E_FAIL; 00751 } 00752 00753 args[0] = obj; 00754 args[1] = NULL; 00755 result = This->mono->mono_runtime_invoke(method, NULL, args, NULL); 00756 if (!result) 00757 { 00758 ERR("Couldn't get result pointer\n"); 00759 return E_FAIL; 00760 } 00761 00762 *ppUnk = *(IUnknown**)This->mono->mono_object_unbox(result); 00763 if (!*ppUnk) 00764 { 00765 ERR("GetIUnknownForObject returned 0\n"); 00766 return E_FAIL; 00767 } 00768 00769 return S_OK; 00770 } 00771 00772 static void get_utf8_args(int *argc, char ***argv) 00773 { 00774 WCHAR **argvw; 00775 int size=0, i; 00776 char *current_arg; 00777 00778 argvw = CommandLineToArgvW(GetCommandLineW(), argc); 00779 00780 for (i=0; i<*argc; i++) 00781 { 00782 size += sizeof(char*); 00783 size += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); 00784 } 00785 size += sizeof(char*); 00786 00787 *argv = HeapAlloc(GetProcessHeap(), 0, size); 00788 current_arg = (char*)(*argv + *argc + 1); 00789 00790 for (i=0; i<*argc; i++) 00791 { 00792 (*argv)[i] = current_arg; 00793 current_arg += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, current_arg, size, NULL, NULL); 00794 } 00795 00796 (*argv)[*argc] = NULL; 00797 00798 HeapFree(GetProcessHeap(), 0, argvw); 00799 } 00800 00801 __int32 WINAPI _CorExeMain(void) 00802 { 00803 int exit_code; 00804 int argc; 00805 char **argv; 00806 MonoDomain *domain; 00807 MonoAssembly *assembly; 00808 WCHAR filename[MAX_PATH]; 00809 char *filenameA; 00810 ICLRRuntimeInfo *info; 00811 RuntimeHost *host; 00812 HRESULT hr; 00813 int i; 00814 00815 get_utf8_args(&argc, &argv); 00816 00817 GetModuleFileNameW(NULL, filename, MAX_PATH); 00818 00819 TRACE("%s", debugstr_w(filename)); 00820 for (i=0; i<argc; i++) 00821 TRACE(" %s", debugstr_a(argv[i])); 00822 TRACE("\n"); 00823 00824 filenameA = WtoA(filename); 00825 if (!filenameA) 00826 return -1; 00827 00828 hr = get_runtime_info(filename, NULL, NULL, 0, 0, FALSE, &info); 00829 00830 if (SUCCEEDED(hr)) 00831 { 00832 hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host); 00833 00834 if (SUCCEEDED(hr)) 00835 hr = RuntimeHost_GetDefaultDomain(host, &domain); 00836 00837 if (SUCCEEDED(hr)) 00838 { 00839 assembly = host->mono->mono_domain_assembly_open(domain, filenameA); 00840 00841 exit_code = host->mono->mono_jit_exec(domain, assembly, argc, argv); 00842 00843 RuntimeHost_DeleteDomain(host, domain); 00844 } 00845 else 00846 exit_code = -1; 00847 00848 ICLRRuntimeInfo_Release(info); 00849 } 00850 else 00851 exit_code = -1; 00852 00853 HeapFree(GetProcessHeap(), 0, argv); 00854 00855 unload_all_runtimes(); 00856 00857 return exit_code; 00858 } 00859 00860 HRESULT RuntimeHost_Construct(const CLRRuntimeInfo *runtime_version, 00861 loaded_mono *loaded_mono, RuntimeHost** result) 00862 { 00863 RuntimeHost *This; 00864 00865 This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); 00866 if ( !This ) 00867 return E_OUTOFMEMORY; 00868 00869 This->ICorRuntimeHost_iface.lpVtbl = &corruntimehost_vtbl; 00870 This->ICLRRuntimeHost_iface.lpVtbl = &CLRHostVtbl; 00871 00872 This->ref = 1; 00873 This->version = runtime_version; 00874 This->mono = loaded_mono; 00875 list_init(&This->domains); 00876 This->default_domain = NULL; 00877 InitializeCriticalSection(&This->lock); 00878 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": RuntimeHost.lock"); 00879 00880 *result = This; 00881 00882 return S_OK; 00883 } 00884 00885 HRESULT RuntimeHost_GetInterface(RuntimeHost *This, REFCLSID clsid, REFIID riid, void **ppv) 00886 { 00887 IUnknown *unk; 00888 HRESULT hr; 00889 00890 if (IsEqualGUID(clsid, &CLSID_CorRuntimeHost)) 00891 { 00892 unk = (IUnknown*)&This->ICorRuntimeHost_iface; 00893 IUnknown_AddRef(unk); 00894 } 00895 else if (IsEqualGUID(clsid, &CLSID_CLRRuntimeHost)) 00896 { 00897 unk = (IUnknown*)&This->ICLRRuntimeHost_iface; 00898 IUnknown_AddRef(unk); 00899 } 00900 else if (IsEqualGUID(clsid, &CLSID_CorMetaDataDispenser) || 00901 IsEqualGUID(clsid, &CLSID_CorMetaDataDispenserRuntime)) 00902 { 00903 hr = MetaDataDispenser_CreateInstance(&unk); 00904 if (FAILED(hr)) 00905 return hr; 00906 } 00907 else if (IsEqualGUID(clsid, &CLSID_CLRDebuggingLegacy)) 00908 { 00909 hr = CorDebug_Create(&This->ICLRRuntimeHost_iface, &unk); 00910 if (FAILED(hr)) 00911 return hr; 00912 } 00913 else 00914 unk = NULL; 00915 00916 if (unk) 00917 { 00918 hr = IUnknown_QueryInterface(unk, riid, ppv); 00919 00920 IUnknown_Release(unk); 00921 00922 return hr; 00923 } 00924 else 00925 FIXME("not implemented for class %s\n", debugstr_guid(clsid)); 00926 00927 return CLASS_E_CLASSNOTAVAILABLE; 00928 } 00929 00930 HRESULT RuntimeHost_Destroy(RuntimeHost *This) 00931 { 00932 struct DomainEntry *cursor, *cursor2; 00933 00934 This->lock.DebugInfo->Spare[0] = 0; 00935 DeleteCriticalSection(&This->lock); 00936 00937 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->domains, struct DomainEntry, entry) 00938 { 00939 list_remove(&cursor->entry); 00940 HeapFree(GetProcessHeap(), 0, cursor); 00941 } 00942 00943 HeapFree( GetProcessHeap(), 0, This ); 00944 return S_OK; 00945 } Generated on Fri May 25 2012 04:22:54 for ReactOS by
1.7.6.1
|