static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *domain, IUnknown **punk) { HRESULT hr; void *args[1]; MonoAssembly *assembly; MonoImage *image; MonoClass *klass; MonoMethod *method; MonoObject *appdomain_object; IUnknown *unk; mono_thread_attach(domain); assembly = mono_domain_assembly_open(domain, "mscorlib"); if (!assembly) { ERR("Cannot load mscorlib\n"); return E_FAIL; } image = mono_assembly_get_image(assembly); if (!image) { ERR("Couldn't get assembly image\n"); return E_FAIL; } klass = mono_class_from_name(image, "System", "AppDomain"); if (!klass) { ERR("Couldn't get class from image\n"); return E_FAIL; } method = mono_class_get_method_from_name(klass, "get_CurrentDomain", 0); if (!method) { ERR("Couldn't get method from class\n"); return E_FAIL; } args[0] = NULL; appdomain_object = mono_runtime_invoke(method, NULL, args, NULL); if (!appdomain_object) { ERR("Couldn't get result pointer\n"); return E_FAIL; } hr = RuntimeHost_GetIUnknownForObject(This, appdomain_object, &unk); if (SUCCEEDED(hr)) { hr = IUnknown_QueryInterface(unk, &IID__AppDomain, (void**)punk); IUnknown_Release(unk); } return hr; }
static void lua_code_exec (Package *pkg) { static lua_State *L = 0; xmono::LuaExecRsp rsp; xmono::LuaExecReq req; MonoThread *thread = mono_thread_attach (mono_domain_get_by_id (0)); do { if (L == 0 && !(L = lua_env_new ())) { rsp.set_level (xmono::LuaExecRsp::err); rsp.set_message ("create a lua_State err."); break; } std::string str((char*)pkg->body, pkg->all_len - sizeof (Package)); //Fixme : 修复头部all_len是总长的问题 if (!req.ParseFromString (str)) { LOGD ("xmono::LuaExecReq ParseFromString err!"); return; } if (luaL_dostring (L, req.lua_code ().c_str ())) { rsp.set_level (xmono::LuaExecRsp::err); rsp.set_message (lua_tostring (L, -1)); break; } rsp.set_level (xmono::LuaExecRsp::debug); rsp.set_message ("exec the lua string ok."); } while (0); mono_thread_detach (thread); std::string out; rsp.SerializeToString (&out); ecmd_send (XMONO_ID_LUA_EXEC_RSP, (uint8_t const*)out.c_str (), out.size ()); return; }
MonoAttachment() : thread(nullptr) { if (!mono_domain_get()) { thread = mono_thread_attach(g_rootDomain); } }
static MonoDomain* domain_attach(MonoDomain *domain) { MonoDomain *prev_domain = mono_domain_get(); if (prev_domain == domain) /* Do not set or restore domain. */ return NULL; mono_thread_attach(domain); return prev_domain; }
void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode) { HRESULT hr; void *args[2]; MonoDomain *domain; MonoAssembly *assembly; MonoImage *image; MonoClass *klass; MonoMethod *method; hr = RuntimeHost_GetDefaultDomain(This, &domain); if (FAILED(hr)) { ERR("Cannot get domain, hr=%x\n", hr); return; } mono_thread_attach(domain); assembly = mono_domain_assembly_open(domain, "mscorlib"); if (!assembly) { ERR("Cannot load mscorlib\n"); return; } image = mono_assembly_get_image(assembly); if (!image) { ERR("Couldn't get assembly image\n"); return; } klass = mono_class_from_name(image, "System", "Environment"); if (!klass) { ERR("Couldn't get class from image\n"); return; } method = mono_class_get_method_from_name(klass, "Exit", 1); if (!method) { ERR("Couldn't get method from class\n"); return; } args[0] = &exitcode; args[1] = NULL; mono_runtime_invoke(method, NULL, args, NULL); ERR("Process should have exited\n"); }
static MonoThread * get_mono_thread () { #ifndef MONO_AGENT thread_t *thr = THREAD_CURRENT_THREAD; MonoThread *ret_thr = NULL; if (NULL == (ret_thr = (MonoThread *) THR_ATTR (thr, TA_MONO_THREAD))) { ret_thr = mono_thread_attach (virtuoso_domain); SET_THR_ATTR (thr, TA_MONO_THREAD, ret_thr); } return ret_thr; #else return NULL; #endif }
void attach_current_thread() { ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized()); MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN); ERR_FAIL_NULL(mono_thread); }
MonoDomain* JniManager::getMonoDomain() { MonoDomain* monoDomain = mono_get_root_domain(); mono_thread_attach(monoDomain); return monoDomain; }
bool VdsViewEventHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us) { if (!_eventClass) return false; int x = ea.getX(); int y = ea.getY(); MonoImage* monoImage = NULL; MonoClass* eventClass = NULL; MonoObject* eventClassObject = NULL; MonoMethod* mousePushMethod = NULL; MonoMethod* mouseReleaseMethod = NULL; MonoMethod* mouseMoveMethod = NULL; MonoMethod* mouseDoubleClickMethod = NULL; MonoMethod* mouseZoomMethod = NULL; MonoMethod* keyDownMethod = NULL; MonoMethod* keyUpMethod = NULL; MonoMethod* layerInSceneChangedMethod = NULL; MonoMethod* gameManagerAddActorEventMethod = NULL; MonoMethod* gameManagerRemoveActorEventMethod = NULL; MonoMethod* gameManagerPlayPlotEventMethod = NULL; MonoMethod* gameManagerStopPlotEventMethod = NULL; MonoMethod* gameManagerPausePlotEventMethod = NULL; MonoMethod* uiEventMethod = NULL; { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_pMutex); monoImage = _monoImage; eventClass = _eventClass; eventClassObject = _eventClassObject; mousePushMethod = _mousePushMethod; mouseReleaseMethod = _mouseReleaseMethod; mouseMoveMethod = _mouseMoveMethod; mouseDoubleClickMethod = _mouseDoubleClickMethod; mouseZoomMethod = _mouseZoomMethod; keyDownMethod = _keyDownMethod; keyUpMethod = _keyUpMethod; layerInSceneChangedMethod = _layerInSceneChangedMethod; gameManagerAddActorEventMethod = _gameManagerAddActorEventMethod; gameManagerRemoveActorEventMethod = _gameManagerRemoveActorEventMethod; gameManagerPlayPlotEventMethod = _gameManagerPlayPlotEventMethod; gameManagerStopPlotEventMethod = _gameManagerStopPlotEventMethod; gameManagerPausePlotEventMethod = _gameManagerPausePlotEventMethod; uiEventMethod = _uiEventMethod; } switch (ea.getEventType()) { case osgGA::GUIEventAdapter::MOVE: { if (!mouseMoveMethod) mouseMoveMethod = mono_class_get_method_from_name(eventClass, "MouseMoveEvent", 3); MonoObject* exception = NULL; void* args[3]; args[0] = &_viewID; args[1] = &x; args[2] = &y; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(mouseMoveMethod, eventClassObject, args, &exception); break; } case osgGA::GUIEventAdapter::PUSH: { if (!mousePushMethod) mousePushMethod = mono_class_get_method_from_name(eventClass, "MouseButtonPressEvent", 4); MonoObject* exception = NULL; int arg0 = 1; void* args[4]; args[0] = &_viewID; if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) arg0 = 1; else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) arg0 = 2; else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) arg0 = 3; args[1] = &arg0; args[2] = &x; args[3] = &y; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(mousePushMethod, eventClassObject, args, &exception); break; } case osgGA::GUIEventAdapter::RELEASE: { if (!mouseReleaseMethod) mouseReleaseMethod = mono_class_get_method_from_name(eventClass, "MouseButtonReleaseEvent", 4); MonoObject* exception = NULL; int arg0 = 1; void* args[4]; args[0] = &_viewID; if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) arg0 = 1; else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) arg0 = 2; else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) arg0 = 3; args[1] = &arg0; args[2] = &x; args[3] = &y; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(mouseReleaseMethod, eventClassObject, args, &exception); break; } case osgGA::GUIEventAdapter::DOUBLECLICK: { if (!mouseDoubleClickMethod) mouseDoubleClickMethod = mono_class_get_method_from_name(eventClass, "MouseDoubleClickEvent", 4); MonoObject* exception = NULL; int arg0 = 1; void* args[4]; args[0] = &_viewID; if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) arg0 = 1; else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) arg0 = 2; else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) arg0 = 3; args[1] = &arg0; args[2] = &x; args[3] = &y; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(mouseDoubleClickMethod, eventClassObject, args, &exception); break; } case osgGA::GUIEventAdapter::KEYDOWN: { if (!keyDownMethod) keyDownMethod = mono_class_get_method_from_name(eventClass, "KeyboardDownEvent", 2); MonoObject* exception = NULL; void* args[2]; args[0] = &_viewID; int keyValue = ea.getKey(); args[1] = &keyValue; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(keyDownMethod, eventClassObject, args, &exception); break; } case osgGA::GUIEventAdapter::KEYUP: { if (!keyUpMethod) keyUpMethod = mono_class_get_method_from_name(eventClass, "KeyboardUpEvent", 2); MonoObject* exception = NULL; void* args[2]; args[0] = &_viewID; int keyValue = ea.getKey(); args[1] = &keyValue; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(keyUpMethod, eventClassObject, args, &exception); break; } case osgGA::GUIEventAdapter::SCROLL: { if (!mouseZoomMethod) mouseZoomMethod = mono_class_get_method_from_name(eventClass, "MouseZoomEvent", 2); MonoObject* exception = NULL; void* args[2]; args[0] = &_viewID; osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion(); int zoomValue = 0; if (sm == osgGA::GUIEventAdapter::SCROLL_DOWN) zoomValue = 1; args[1] = &zoomValue; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(mouseZoomMethod, eventClassObject, args, &exception); break; } case osgGA::GUIEventAdapter::USER: { osg::ref_ptr<osg::Referenced> userData = const_cast<osg::Referenced*>(ea.getUserData()); UserEventData* data = static_cast<UserEventData*>(userData.get()); switch (data->_eventType) { case UserEventData::LAYERCHANGED: { if (!layerInSceneChangedMethod) layerInSceneChangedMethod = mono_class_get_method_from_name(eventClass, "LayerInSceneChangedEvent", 1); MonoObject* exception = NULL; void* args[1]; args[0] = &_viewID; _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(layerInSceneChangedMethod, eventClassObject, args, &exception); break; } case UserEventData::UI_EVENT: { if (!uiEventMethod) uiEventMethod = mono_class_get_method_from_name(eventClass, "UIEvent", 3); void* widthData = data->_data; std::vector<std::string>* dList = (std::vector<std::string>*)widthData; MonoDomain* domain = mono_object_get_domain(eventClassObject); MonoObject* exception = NULL; void* args[3]; args[0] = &_viewID; args[1] = mono_string_new(domain, dList->at(0).c_str()); args[2] = mono_string_new(domain, dList->at(1).c_str()); _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(uiEventMethod, eventClassObject, args, &exception); break; } case UserEventData::GAMEMANAGER_ACTORADD: { if (!gameManagerAddActorEventMethod) gameManagerAddActorEventMethod = mono_class_get_method_from_name(eventClass, "GameLayerAddActorEvent", 2); MonoDomain* domain = mono_object_get_domain(eventClassObject); MonoObject* exception = NULL; void* args[2]; args[0] = &_viewID; args[1] = mono_string_new(domain, dynamic_cast<VirtualDataSceneBase::ActorBase*>(data->_eventObject.get())->getId().c_str()); _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(gameManagerAddActorEventMethod, eventClassObject, args, &exception); break; } case UserEventData::GAMEMANAGER_ACTORREMOVE: { if (!gameManagerRemoveActorEventMethod) gameManagerRemoveActorEventMethod = mono_class_get_method_from_name(eventClass, "GameLayerRemoveActorEvent", 2); MonoDomain* domain = mono_object_get_domain(eventClassObject); MonoObject* exception = NULL; void* args[2]; args[0] = &_viewID; args[1] = mono_string_new(domain, dynamic_cast<VirtualDataSceneBase::ActorBase*>(data->_eventObject.get())->getId().c_str()); _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(gameManagerRemoveActorEventMethod, eventClassObject, args, &exception); break; } case UserEventData::GAMEMANAGER_PLAYPLOT: { if (!gameManagerPlayPlotEventMethod) gameManagerPlayPlotEventMethod = mono_class_get_method_from_name(eventClass, "PlayPlotScriptEvent", 3); void* widthData = data->_data; std::vector<std::string>* dList = (std::vector<std::string>*)widthData; MonoDomain* domain = mono_object_get_domain(eventClassObject); MonoObject* exception = NULL; void* args[3]; args[0] = &_viewID; args[1] = mono_string_new(domain, dList->at(0).c_str()); args[2] = mono_string_new(domain, dList->at(1).c_str()); _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(gameManagerPlayPlotEventMethod, eventClassObject, args, &exception); break; } case UserEventData::GAMEMANAGER_STOPPLOT: { if (!gameManagerStopPlotEventMethod) gameManagerStopPlotEventMethod = mono_class_get_method_from_name(eventClass, "StopPlotScriptEvent", 2); MonoDomain* domain = mono_object_get_domain(eventClassObject); MonoObject* exception = NULL; void* args[2]; args[0] = &_viewID; args[1] = mono_string_new(domain, dynamic_cast<VirtualDataSceneBase::ActorBase*>(data->_eventObject.get())->getId().c_str()); _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(gameManagerStopPlotEventMethod, eventClassObject, args, &exception); break; } case UserEventData::GAMEMANAGER_PAUSEPLOT: { if (!gameManagerPausePlotEventMethod) gameManagerPausePlotEventMethod = mono_class_get_method_from_name(eventClass, "PausePlotScriptEvent", 2); MonoDomain* domain = mono_object_get_domain(eventClassObject); MonoObject* exception = NULL; void* args[2]; args[0] = &_viewID; args[1] = mono_string_new(domain, dynamic_cast<VirtualDataSceneBase::ActorBase*>(data->_eventObject.get())->getId().c_str()); _eventThread = mono_thread_attach(mono_get_root_domain()); mono_runtime_invoke(gameManagerPausePlotEventMethod, eventClassObject, args, &exception); break; } default: break; } break; } case osgGA::GUIEventAdapter::CLOSE_WINDOW: case osgGA::GUIEventAdapter::QUIT_APPLICATION: { //mono_thread_detach(_eventThread); break; } default: break; } return false; }
static void CDECL ReallyFixupVTable(struct dll_fixup *fixup) { HRESULT hr=S_OK; WCHAR filename[MAX_PATH]; ICLRRuntimeInfo *info=NULL; RuntimeHost *host; char *filenameA; MonoImage *image=NULL; MonoAssembly *assembly=NULL; MonoImageOpenStatus status=0; MonoDomain *domain; if (fixup->done) return; /* It's possible we'll have two threads doing this at once. This is * considered preferable to the potential deadlock if we use a mutex. */ GetModuleFileNameW(fixup->dll, filename, MAX_PATH); TRACE("%p,%p,%s\n", fixup, fixup->dll, debugstr_w(filename)); filenameA = WtoA(filename); if (!filenameA) hr = E_OUTOFMEMORY; if (SUCCEEDED(hr)) hr = get_runtime_info(filename, NULL, NULL, 0, 0, FALSE, &info); if (SUCCEEDED(hr)) hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host); if (SUCCEEDED(hr)) hr = RuntimeHost_GetDefaultDomain(host, &domain); if (SUCCEEDED(hr)) { mono_thread_attach(domain); assembly = mono_assembly_open(filenameA, &status); } if (assembly) { int i; /* Mono needs an image that belongs to an assembly. */ image = mono_assembly_get_image(assembly); if (fixup->fixup->type & COR_VTABLE_32BIT) { DWORD *vtable = fixup->vtable; DWORD *tokens = fixup->tokens; for (i=0; i<fixup->fixup->count; i++) { TRACE("%x\n", tokens[i]); vtable[i] = PtrToUint(mono_marshal_get_vtfixup_ftnptr( image, tokens[i], fixup->fixup->type)); } } fixup->done = TRUE; } if (info != NULL) ICLRRuntimeInfo_Release(info); HeapFree(GetProcessHeap(), 0, filenameA); if (!fixup->done) { ERR("unable to fixup vtable, hr=%x, status=%d\n", hr, status); /* If we returned now, we'd get an infinite loop. */ assert(0); } }
/* Create an instance of a type given its name, by calling its constructor with * no arguments. Note that result MUST be in the stack, or the garbage * collector may free it prematurely. */ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name, MonoDomain *domain, MonoObject **result) { HRESULT hr=S_OK; char *nameA=NULL; MonoType *type; MonoClass *klass; MonoObject *obj; if (!domain) hr = RuntimeHost_GetDefaultDomain(This, &domain); if (SUCCEEDED(hr)) { nameA = WtoA(name); if (!nameA) hr = E_OUTOFMEMORY; } if (SUCCEEDED(hr)) { mono_thread_attach(domain); type = mono_reflection_type_from_name(nameA, NULL); if (!type) { ERR("Cannot find type %s\n", debugstr_w(name)); hr = E_FAIL; } } if (SUCCEEDED(hr)) { klass = mono_class_from_mono_type(type); if (!klass) { ERR("Cannot convert type %s to a class\n", debugstr_w(name)); hr = E_FAIL; } } if (SUCCEEDED(hr)) { obj = mono_object_new(domain, klass); if (!obj) { ERR("Cannot allocate object of type %s\n", debugstr_w(name)); hr = E_FAIL; } } if (SUCCEEDED(hr)) { /* FIXME: Detect exceptions from the constructor? */ mono_runtime_object_init(obj); *result = obj; } HeapFree(GetProcessHeap(), 0, nameA); return hr; }
static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* iface, LPCWSTR pwzAssemblyPath, LPCWSTR pwzTypeName, LPCWSTR pwzMethodName, LPCWSTR pwzArgument, DWORD *pReturnValue) { RuntimeHost *This = impl_from_ICLRRuntimeHost( iface ); HRESULT hr; MonoDomain *domain; MonoAssembly *assembly; MonoImage *image; MonoClass *klass; MonoMethod *method; MonoObject *result; MonoString *str; void *args[2]; char *filenameA = NULL, *classA = NULL, *methodA = NULL; char *argsA = NULL, *ns; TRACE("(%p,%s,%s,%s,%s)\n", iface, debugstr_w(pwzAssemblyPath), debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument)); hr = RuntimeHost_GetDefaultDomain(This, &domain); if(hr != S_OK) { ERR("Couldn't get Default Domain\n"); return hr; } hr = E_FAIL; mono_thread_attach(domain); filenameA = WtoA(pwzAssemblyPath); assembly = mono_domain_assembly_open(domain, filenameA); if (!assembly) { ERR("Cannot open assembly %s\n", filenameA); goto cleanup; } image = mono_assembly_get_image(assembly); if (!image) { ERR("Couldn't get assembly image\n"); goto cleanup; } classA = WtoA(pwzTypeName); ns = strrchr(classA, '.'); *ns = '\0'; klass = mono_class_from_name(image, classA, ns+1); if (!klass) { ERR("Couldn't get class from image\n"); goto cleanup; } methodA = WtoA(pwzMethodName); method = mono_class_get_method_from_name(klass, methodA, 1); if (!method) { ERR("Couldn't get method from class\n"); goto cleanup; } /* The .NET function we are calling has the following declaration * public static int functionName(String param) */ argsA = WtoA(pwzArgument); str = mono_string_new(domain, argsA); args[0] = str; args[1] = NULL; result = mono_runtime_invoke(method, NULL, args, NULL); if (!result) ERR("Couldn't get result pointer\n"); else { *pReturnValue = *(DWORD*)mono_object_unbox(result); hr = S_OK; } cleanup: HeapFree(GetProcessHeap(), 0, filenameA); HeapFree(GetProcessHeap(), 0, classA); HeapFree(GetProcessHeap(), 0, argsA); HeapFree(GetProcessHeap(), 0, methodA); return hr; }
HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) { static const WCHAR wszAssembly[] = {'A','s','s','e','m','b','l','y',0}; static const WCHAR wszCodebase[] = {'C','o','d','e','B','a','s','e',0}; static const WCHAR wszClass[] = {'C','l','a','s','s',0}; static const WCHAR wszFileSlash[] = {'f','i','l','e',':','/','/','/',0}; static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0}; static const WCHAR wszInprocServer32[] = {'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2',0}; static const WCHAR wszDLL[] = {'.','d','l','l',0}; WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) + ARRAYSIZE(wszInprocServer32) - 1]; MonoDomain *domain; MonoAssembly *assembly; ICLRRuntimeInfo *info = NULL; RuntimeHost *host; HRESULT hr; HKEY key, subkey; LONG res; int offset = 0; DWORD numKeys, keyLength; WCHAR codebase[MAX_PATH + 8]; WCHAR classname[350], subkeyName[256]; WCHAR filename[MAX_PATH]; DWORD dwBufLen = 350; lstrcpyW(path, wszCLSIDSlash); StringFromGUID2(riid, path + lstrlenW(wszCLSIDSlash), CHARS_IN_GUID); lstrcatW(path, wszInprocServer32); TRACE("Registry key: %s\n", debugstr_w(path)); res = RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, KEY_READ, &key); if (res == ERROR_FILE_NOT_FOUND) return CLASS_E_CLASSNOTAVAILABLE; res = RegGetValueW( key, NULL, wszClass, RRF_RT_REG_SZ, NULL, classname, &dwBufLen); if(res != ERROR_SUCCESS) { WARN("Class value cannot be found.\n"); hr = CLASS_E_CLASSNOTAVAILABLE; goto cleanup; } TRACE("classname (%s)\n", debugstr_w(classname)); dwBufLen = MAX_PATH + 8; res = RegGetValueW( key, NULL, wszCodebase, RRF_RT_REG_SZ, NULL, codebase, &dwBufLen); if(res == ERROR_SUCCESS) { /* Strip file:/// */ if(strncmpW(codebase, wszFileSlash, strlenW(wszFileSlash)) == 0) offset = strlenW(wszFileSlash); strcpyW(filename, codebase + offset); } else { WCHAR assemblyname[MAX_PATH + 8]; hr = CLASS_E_CLASSNOTAVAILABLE; WARN("CodeBase value cannot be found, trying Assembly.\n"); /* get the last subkey of InprocServer32 */ res = RegQueryInfoKeyW(key, 0, 0, 0, &numKeys, 0, 0, 0, 0, 0, 0, 0); if (res != ERROR_SUCCESS || numKeys == 0) goto cleanup; numKeys--; keyLength = sizeof(subkeyName) / sizeof(WCHAR); res = RegEnumKeyExW(key, numKeys, subkeyName, &keyLength, 0, 0, 0, 0); if (res != ERROR_SUCCESS) goto cleanup; res = RegOpenKeyExW(key, subkeyName, 0, KEY_READ, &subkey); if (res != ERROR_SUCCESS) goto cleanup; dwBufLen = MAX_PATH + 8; res = RegGetValueW(subkey, NULL, wszAssembly, RRF_RT_REG_SZ, NULL, assemblyname, &dwBufLen); RegCloseKey(subkey); if (res != ERROR_SUCCESS) goto cleanup; hr = get_file_from_strongname(assemblyname, filename, MAX_PATH); if (!SUCCEEDED(hr)) { /* * The registry doesn't have a CodeBase entry and it's not in the GAC. * * Use the Assembly Key to retrieve the filename. * Assembly : REG_SZ : AssemblyName, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null */ WCHAR *ns; WARN("Attempt to load from the application directory.\n"); GetModuleFileNameW(NULL, filename, MAX_PATH); ns = strrchrW(filename, '\\'); *(ns+1) = '\0'; ns = strchrW(assemblyname, ','); *(ns) = '\0'; strcatW(filename, assemblyname); *(ns) = '.'; strcatW(filename, wszDLL); } } TRACE("filename (%s)\n", debugstr_w(filename)); *ppObj = NULL; hr = get_runtime_info(filename, NULL, NULL, 0, 0, FALSE, &info); if (SUCCEEDED(hr)) { hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host); if (SUCCEEDED(hr)) hr = RuntimeHost_GetDefaultDomain(host, &domain); if (SUCCEEDED(hr)) { MonoImage *image; MonoClass *klass; MonoObject *result; IUnknown *unk = NULL; char *filenameA, *ns; char *classA; hr = CLASS_E_CLASSNOTAVAILABLE; mono_thread_attach(domain); filenameA = WtoA(filename); assembly = mono_domain_assembly_open(domain, filenameA); HeapFree(GetProcessHeap(), 0, filenameA); if (!assembly) { ERR("Cannot open assembly %s\n", filenameA); goto cleanup; } image = mono_assembly_get_image(assembly); if (!image) { ERR("Couldn't get assembly image\n"); goto cleanup; } classA = WtoA(classname); ns = strrchr(classA, '.'); *ns = '\0'; klass = mono_class_from_name(image, classA, ns+1); HeapFree(GetProcessHeap(), 0, classA); if (!klass) { ERR("Couldn't get class from image\n"); goto cleanup; } /* * Use the default constructor for the .NET class. */ result = mono_object_new(domain, klass); mono_runtime_object_init(result); hr = RuntimeHost_GetIUnknownForObject(host, result, &unk); if (SUCCEEDED(hr)) { hr = IUnknown_QueryInterface(unk, &IID_IUnknown, ppObj); IUnknown_Release(unk); } else hr = CLASS_E_CLASSNOTAVAILABLE; } else hr = CLASS_E_CLASSNOTAVAILABLE; } else hr = CLASS_E_CLASSNOTAVAILABLE; cleanup: if(info) ICLRRuntimeInfo_Release(info); RegCloseKey(key); return hr; }
static void replace_method (Package *pkg) { xmono::ReplaceMethodReq req; xmono::ReplaceMethodRsp rsp; std::string str((char*)pkg->body, pkg->all_len - sizeof (Package)); if (!req.ParseFromString (str)) { LOGD ("xmono::ReplaceMethodReq ParseFromString err!"); return; } std::string err; void *p, *old_p; uint8_t *code; int code_size; MonoMethodHeader *mh; MonoThread *thread; MonoMethod *new_method; MonoDomain *domain; MonoMethod * method = get_method_with_token (req.image_name ().c_str (), req.method_token ()); if (!method) { rsp.set_err (false); rsp.set_msg (helper_last_err ()); goto replace_method_end; } domain = mono_domain_get_by_id (req.domain_id ()); if (!domain) { rsp.set_err (false); rsp.set_msg ("can not get the domain from id"); goto replace_method_end; } mh = mono_method_get_header (method); if (req.ex_size () != mono_method_header_get_num_clauses (mh)) { rsp.set_err (false); rsp.set_msg ("ex size != mono_method_header_clauses size!"); goto replace_method_end; } for (int i = 0; i < req.ex_size (); i++) { xmono::ReplaceMethodReq_ExceptionClause const &e = req.ex (i); void *iter = 0; MonoExceptionClause *clauses = &mh->clauses[i]; MonoExceptionClause *old_e = (MonoExceptionClause*)iter; old_e->try_offset = e.try_offset (); old_e->try_len = e.try_len (); old_e->handler_offset = e.handler_offset (); old_e->handler_len = e.handler_len (); } code = new uint8_t[req.new_code ().size ()]; memcpy (code, req.new_code ().c_str (), req.new_code ().size ()); mh->code = code; mh->code_size = req.new_code ().size (); thread = mono_thread_attach (domain); /*128 是一个估计值, 在未来可能不稳定, 但当前只能如此*/ new_method = (MonoMethod*)calloc (128, 1); /*这个地方用malloc优于用new*/ memcpy (new_method, method, 128); pthread_mutex_lock (&replace_mutex); replace_method_dict[new_method] = true; pthread_mutex_unlock (&replace_mutex); p = mono_compile_method (new_method); memcpy (hooked_method_dict[method]->specific_hook + 4, &p, 4); pthread_mutex_lock (&hooked_mutex); old_p = mono_jit_info_get_code_start (hooked_method_dict[method]->jinfo); pthread_mutex_unlock (&hooked_mutex); mono_thread_detach (thread); LOGD ("compile method, new ptr : %p, old ptr : %p", p, old_p); rsp.set_err (true); rsp.set_msg ("replace_method successful."); replace_method_end: std::string out; rsp.SerializeToString (&out); ecmd_send (XMONO_ID_REPLACE_METHOD_RSP, (uint8_t const*)out.c_str (), out.size ()); return; }
void CPipeServer::InitMono() { HMODULE hMono=GetModuleHandle(L"mono.dll"); if (!hMono) { //this process doesn't use mono.dll Perhaps it's renamed. Find a module that exports mono_thread_attach HANDLE ths=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); if (ths != INVALID_HANDLE_VALUE) { MODULEENTRY32 me; me.dwSize = sizeof(me); if (Module32First(ths, &me)) { do { if (GetProcAddress(me.hModule, "mono_thread_attach")) { hMono = me.hModule; break; } } while (Module32Next(ths, &me)); } CloseHandle(ths); } } WriteQword((UINT64)hMono); if (hMono) { std::stringstream x; x.clear(); x << "Mono dll found at " << std::hex << hMono <<"\n"; OutputDebugStringA(x.str().c_str()); if (attached==FALSE) { g_free=(G_FREE)GetProcAddress(hMono, "g_free"); mono_get_root_domain=(MONO_GET_ROOT_DOMAIN)GetProcAddress(hMono, "mono_get_root_domain"); mono_thread_attach=(MONO_THREAD_ATTACH)GetProcAddress(hMono, "mono_thread_attach"); mono_thread_detach=(MONO_THREAD_DETACH)GetProcAddress(hMono, "mono_thread_detach"); mono_object_get_class=(MONO_OBJECT_GET_CLASS)GetProcAddress(hMono, "mono_object_get_class"); mono_domain_foreach=(MONO_DOMAIN_FOREACH)GetProcAddress(hMono, "mono_domain_foreach"); mono_domain_set=(MONO_DOMAIN_SET)GetProcAddress(hMono, "mono_domain_set"); mono_assembly_foreach=(MONO_ASSEMBLY_FOREACH)GetProcAddress(hMono, "mono_assembly_foreach"); mono_assembly_get_image=(MONO_ASSEMBLY_GET_IMAGE)GetProcAddress(hMono, "mono_assembly_get_image"); mono_image_get_name=(MONO_IMAGE_GET_NAME)GetProcAddress(hMono, "mono_image_get_name"); mono_image_get_table_info=(MONO_IMAGE_GET_TABLE_INFO)GetProcAddress(hMono, "mono_image_get_table_info"); mono_image_rva_map=(MONO_IMAGE_RVA_MAP)GetProcAddress(hMono, "mono_image_rva_map"); mono_table_info_get_rows=(MONO_TABLE_INFO_GET_ROWS)GetProcAddress(hMono, "mono_table_info_get_rows"); mono_metadata_decode_row_col=(MONO_METADATA_DECODE_ROW_COL)GetProcAddress(hMono, "mono_metadata_decode_row_col"); mono_metadata_string_heap=(MONO_METADATA_STRING_HEAP)GetProcAddress(hMono, "mono_metadata_string_heap"); mono_class_get=(MONO_CLASS_GET)GetProcAddress(hMono, "mono_class_get"); mono_class_from_name_case=(MONO_CLASS_FROM_NAME_CASE)GetProcAddress(hMono, "mono_class_from_name_case"); mono_class_get_name=(MONO_CLASS_GET_NAME)GetProcAddress(hMono, "mono_class_get_name"); mono_class_get_namespace=(MONO_CLASS_GET_NAMESPACE)GetProcAddress(hMono, "mono_class_get_namespace"); mono_class_get_methods=(MONO_CLASS_GET_METHODS)GetProcAddress(hMono, "mono_class_get_methods"); mono_class_get_method_from_name=(MONO_CLASS_GET_METHOD_FROM_NAME)GetProcAddress(hMono, "mono_class_get_method_from_name"); mono_class_get_fields=(MONO_CLASS_GET_FIELDS)GetProcAddress(hMono, "mono_class_get_fields"); mono_class_get_parent=(MONO_CLASS_GET_PARENT)GetProcAddress(hMono, "mono_class_get_parent"); mono_class_vtable=(MONO_CLASS_VTABLE)GetProcAddress(hMono, "mono_class_vtable"); mono_class_num_fields=(MONO_CLASS_NUM_FIELDS)GetProcAddress(hMono, "mono_class_num_fields"); mono_class_num_methods=(MONO_CLASS_NUM_METHODS)GetProcAddress(hMono, "mono_class_num_methods"); mono_field_get_name=(MONO_FIELD_GET_NAME)GetProcAddress(hMono, "mono_field_get_name"); mono_field_get_type=(MONO_FIELD_GET_TYPE)GetProcAddress(hMono, "mono_field_get_type"); mono_field_get_parent=(MONO_FIELD_GET_PARENT)GetProcAddress(hMono, "mono_field_get_parent"); mono_field_get_offset=(MONO_FIELD_GET_OFFSET)GetProcAddress(hMono, "mono_field_get_offset"); mono_field_get_flags = (MONO_FIELD_GET_FLAGS)GetProcAddress(hMono, "mono_field_get_flags"); mono_type_get_name=(MONO_TYPE_GET_NAME)GetProcAddress(hMono, "mono_type_get_name"); mono_type_get_type=(MONO_TYPE_GET_TYPE)GetProcAddress(hMono, "mono_type_get_type"); mono_method_get_name=(MONO_METHOD_GET_NAME)GetProcAddress(hMono, "mono_method_get_name"); mono_method_get_class=(MONO_METHOD_GET_CLASS)GetProcAddress(hMono, "mono_method_get_class"); mono_method_get_header=(MONO_METHOD_GET_HEADER)GetProcAddress(hMono, "mono_method_get_header"); mono_method_signature=(MONO_METHOD_SIG)GetProcAddress(hMono, "mono_method_signature"); mono_method_get_param_names = (MONO_METHOD_GET_PARAM_NAMES)GetProcAddress(hMono, "mono_method_get_param_names"); mono_signature_get_desc = (MONO_SIGNATURE_GET_DESC)GetProcAddress(hMono, "mono_signature_get_desc"); mono_signature_get_param_count = (MONO_SIGNATURE_GET_PARAM_COUNT)GetProcAddress(hMono, "mono_signature_get_param_count"); mono_signature_get_return_type = (MONO_SIGNATURE_GET_RETURN_TYPE)GetProcAddress(hMono, "mono_signature_get_return_type"); mono_compile_method=(MONO_COMPILE_METHOD)GetProcAddress(hMono, "mono_compile_method"); mono_free_method=(MONO_FREE_METHOD)GetProcAddress(hMono, "mono_free_method"); mono_jit_info_table_find=(MONO_JIT_INFO_TABLE_FIND)GetProcAddress(hMono, "mono_jit_info_table_find"); mono_jit_info_get_method=(MONO_JIT_INFO_GET_METHOD)GetProcAddress(hMono, "mono_jit_info_get_method"); mono_jit_info_get_code_start=(MONO_JIT_INFO_GET_CODE_START)GetProcAddress(hMono, "mono_jit_info_get_code_start"); mono_jit_info_get_code_size=(MONO_JIT_INFO_GET_CODE_SIZE)GetProcAddress(hMono, "mono_jit_info_get_code_size"); mono_method_header_get_code=(MONO_METHOD_HEADER_GET_CODE)GetProcAddress(hMono, "mono_method_header_get_code"); mono_disasm_code=(MONO_DISASM_CODE)GetProcAddress(hMono, "mono_disasm_code"); mono_vtable_get_static_field_data = (MONO_VTABLE_GET_STATIC_FIELD_DATA)GetProcAddress(hMono, "mono_vtable_get_static_field_data"); if (mono_get_root_domain==NULL) OutputDebugStringA("mono_get_root_domain not assigned"); if (mono_thread_attach==NULL) OutputDebugStringA("mono_thread_attach not assigned"); if (mono_object_get_class==NULL) OutputDebugStringA("mono_object_get_class not assigned"); if (mono_class_get_name==NULL) OutputDebugStringA("mono_class_get_name not assigned"); if (mono_domain_foreach==NULL) OutputDebugStringA("mono_domain_foreach not assigned"); if (mono_domain_set==NULL) OutputDebugStringA("mono_domain_set not assigned"); if (mono_assembly_foreach==NULL) OutputDebugStringA("mono_assembly_foreach not assigned"); if (mono_assembly_get_image==NULL) OutputDebugStringA("mono_assembly_get_image not assigned"); if (mono_image_get_name==NULL) OutputDebugStringA("mono_image_get_name not assigned"); mono_selfthread=mono_thread_attach(mono_get_root_domain()); attached=TRUE; } else OutputDebugStringA("Already attached"); } }