ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

corruntimehost.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.