HRESULT CorHost::GetDomainsExposedObject(AppDomain* pDomain, IUnknown** pAppDomain) { HRESULT hr = S_OK; IUnknown* punk = NULL; Thread* pThread = GetThread(); if (!pThread) return E_UNEXPECTED; BOOL fWasGCEnabled = !pThread->PreemptiveGCDisabled(); if (fWasGCEnabled) pThread->DisablePreemptiveGC(); BEGINCANNOTTHROWCOMPLUSEXCEPTION(); COMPLUS_TRY { punk = GetDomainsExposedObjectWorker(pThread, pDomain); } COMPLUS_CATCH { hr = SecurityHelper::MapToHR(GETTHROWABLE()); } COMPLUS_END_CATCH if (fWasGCEnabled) pThread->EnablePreemptiveGC(); if(SUCCEEDED(hr)) *pAppDomain = punk; ENDCANNOTTHROWCOMPLUSEXCEPTION(); return hr; }
// Collect the requested generation. HRESULT CorHost::Collect( LONG Generation) { HRESULT hr = E_FAIL; if (Generation > (long) g_pGCHeap->GetMaxGeneration()) hr = E_INVALIDARG; else { Thread *pThread = GetThread(); BOOL bIsCoopMode = pThread->PreemptiveGCDisabled(); // Put thread into co-operative mode, which is how GC must run. if (!bIsCoopMode) pThread->DisablePreemptiveGC(); COMPLUS_TRY { hr = g_pGCHeap->GarbageCollect(Generation); } COMPLUS_CATCH { hr = SetupErrorInfo(GETTHROWABLE()); } COMPLUS_END_CATCH // Return mode as requird. if (!bIsCoopMode) pThread->EnablePreemptiveGC(); } return (hr); }
RegionInfoTable* RegionInfoTable::CreateInstance() { THROWSCOMPLUSEXCEPTION(); if (m_pDefaultTable==NULL) { Thread* pThread = GetThread(); pThread->EnablePreemptiveGC(); LOCKCOUNTINCL("CreateInstance in regioninfotable.cpp"); \ EnterCriticalSection(&m_ProtectDefaultTable); pThread->DisablePreemptiveGC(); EE_TRY_FOR_FINALLY { //Make sure that nobody allocated the table before us. if (m_pDefaultTable==NULL) { //Allocate the default table and verify that we got one. m_pDefaultTable = AllocateTable(); if (m_pDefaultTable==NULL) { COMPlusThrowOM(); } } } EE_FINALLY { //We need to leave the critical section regardless of whether //or not we were successful in allocating the table. LeaveCriticalSection(&m_ProtectDefaultTable); LOCKCOUNTDECL("CreateInstance in regioninfotable.cpp"); \ } EE_END_FINALLY; }
uint32_t CLREventStatic::Wait(uint32_t dwMilliseconds, bool bAlertable) { DWORD result = WAIT_FAILED; if (m_fInitialized) { bool disablePreemptive = false; Thread * pCurThread = GetThread(); if (NULL != pCurThread) { if (pCurThread->PreemptiveGCDisabled()) { pCurThread->EnablePreemptiveGC(); disablePreemptive = true; } } // TODO: Implement result = WAIT_OBJECT_0; if (disablePreemptive) { pCurThread->DisablePreemptiveGC(); } } return result; }
bool GCToEEInterface::EnablePreemptiveGC() { bool bToggleGC = false; Thread* pThread = ::GetThread(); if (pThread) { bToggleGC = !!pThread->PreemptiveGCDisabled(); if (bToggleGC) { pThread->EnablePreemptiveGC(); } } return bToggleGC; }
HRESULT CorHost::CreateEvidence(IUnknown **pEvidence) { HRESULT hr = S_OK; if (!pEvidence) return E_POINTER; BEGINCANNOTTHROWCOMPLUSEXCEPTION(); // Create the domain. Thread* pThread = GetThread(); if (!pThread) IfFailGo(E_UNEXPECTED); IfFailGo(QuickCOMStartup()); BOOL fWasGCEnabled; fWasGCEnabled = !pThread->PreemptiveGCDisabled(); if (fWasGCEnabled) pThread->DisablePreemptiveGC(); COMPLUS_TRY { struct _gc { OBJECTREF pEvidence; } gc; ZeroMemory(&gc, sizeof(gc)); MethodTable* pMT = g_Mscorlib.GetClass(CLASS__EVIDENCE); GCPROTECT_BEGIN(gc); gc.pEvidence = AllocateObject(pMT); IfFailThrow(QuickCOMStartup()); *pEvidence = GetComIPFromObjectRef((OBJECTREF*) &gc.pEvidence); GCPROTECT_END(); } COMPLUS_CATCH { hr = SecurityHelper::MapToHR(GETTHROWABLE()); } COMPLUS_END_CATCH if (fWasGCEnabled) pThread->EnablePreemptiveGC(); ErrExit: ENDCANNOTTHROWCOMPLUSEXCEPTION(); return hr; }
HRESULT STDMETHODCALLTYPE ICorDBPrivHelperImpl::CreateManagedObject( /*in*/ WCHAR *wszAssemblyName, /*in*/ WCHAR *wszModuleName, /*in*/ mdTypeDef classToken, /*in*/ void *rawData, /*out*/ IUnknown **ppUnk) { _ASSERTE(TypeFromToken((mdTypeDef)classToken) == mdtTypeDef); _ASSERTE(wszAssemblyName && wszModuleName && ppUnk); if (!wszAssemblyName || !wszModuleName || classToken == mdTokenNil) return E_INVALIDARG; if (!ppUnk) return E_POINTER; HRESULT hr = S_OK; BEGINCANNOTTHROWCOMPLUSEXCEPTION(); // This will set up a managed thread object if one does not already exist // for this particular thread. Thread* pThread = SetupThread(); if (pThread == NULL) { hr = E_OUTOFMEMORY; goto Exit; } // Start up COM Interop if (FAILED(hr = QuickCOMStartup())) goto Exit; { // Don't want to be interrupted... BOOL fWasGCEnabled = !pThread->PreemptiveGCDisabled(); if (fWasGCEnabled) pThread->DisablePreemptiveGC(); Assembly *pAssembly; Module *pModule; if (GetAppDomain() == NULL) hr = E_INVALIDARG; else { // Try and load the assembly, given the name provided. OBJECTREF pThrowable = NULL; GCPROTECT_BEGIN(pThrowable); hr = AssemblySpec::LoadAssembly(wszAssemblyName, &pAssembly, &pThrowable); GCPROTECT_END(); if (SUCCEEDED(hr)) { _ASSERTE(pAssembly); // Try and load the module, given the name provided. hr = pAssembly->GetModuleFromFilename(wszModuleName, &pModule); if (SUCCEEDED(hr)) { _ASSERTE(pModule); // If the class isn't known,then don't try and create it. if (!pModule->GetMDImport()->IsValidToken(classToken)) hr = E_INVALIDARG; else { COMPLUS_TRY { OBJECTREF obj = NULL; GCPROTECT_BEGIN(obj); // Now try and get the TypeHandle for the given token NameHandle nameHandle(pModule, classToken); TypeHandle typeHandle = pAssembly->LoadTypeHandle(&nameHandle, &obj); // If an exception was thrown at some point, convert // it to an HRESULT if (obj != NULL) hr = SecurityHelper::MapToHR(obj); // No longer need the object, can be GC'd if desired obj = NULL; if (SUCCEEDED(hr)) { _ASSERTE(typeHandle.AsMethodTable()); MethodTable *pMT = typeHandle.AsMethodTable(); if (!pMT->GetClass()->IsValueClass() || pMT->ContainsPointers()) hr = CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS; if (SUCCEEDED(hr)) { // Now run the class initialiser if (!pMT->CheckRunClassInit(&obj)) hr = SecurityHelper::MapToHR(obj); // No longer need the object, can be GC'd if // desired obj = NULL; if (SUCCEEDED(hr)) { // If successful, allocate an instance of // the class // This may throw an // OutOfMemoryException, but the below // COMPLUS_CATCH should handle it. If // the class is a ValueClass, the // created object will be a boxed // ValueClass. obj = AllocateObject(pMT); // Now create a COM wrapper around // this object. Note that this can // also throw. *ppUnk = GetComIPFromObjectRef(&obj); _ASSERTE(ppUnk); // This is the nasty part. We're gonna // copy the raw data we're given over // the new instance of the value // class... CopyValueClass(obj->UnBox(), rawData, pMT, obj->GetAppDomain()); // No longer need the object, can be GC'd // if desired obj = NULL; } } } GCPROTECT_END(); // obj } COMPLUS_CATCH { // If there's an exception, convert it to an HR hr = SecurityHelper::MapToHR(GETTHROWABLE()); } COMPLUS_END_CATCH } } } } if (fWasGCEnabled) pThread->EnablePreemptiveGC(); } Exit: ENDCANNOTTHROWCOMPLUSEXCEPTION(); return (hr); }
// Creates a domain in the runtime. The identity array is // a pointer to an array TYPE containing IIdentity objects defining // the security identity. HRESULT CorHost::CreateDomainEx(LPCWSTR pwzFriendlyName, IUnknown* pSetup, // Optional IUnknown* pEvidence, // Optional IUnknown ** pAppDomain) { HRESULT hr = S_OK; if(!pwzFriendlyName) return E_POINTER; if(pAppDomain == NULL) return E_POINTER; if(g_RefCount == 0) return E_FAIL; BEGINCANNOTTHROWCOMPLUSEXCEPTION(); // This will set up a managed thread object if one does not already exist // for this particular thread. Thread* pThread = SetupThread(); if (pThread == NULL) { hr = E_OUTOFMEMORY; goto Exit; } if (!pThread) { hr = E_UNEXPECTED; goto Exit; } if (FAILED(hr = QuickCOMStartup())) goto Exit; BOOL fWasGCEnabled; fWasGCEnabled = !pThread->PreemptiveGCDisabled(); if (fWasGCEnabled) pThread->DisablePreemptiveGC(); COMPLUS_TRY { struct _gc { STRINGREF pName; OBJECTREF pSetup; OBJECTREF pEvidence; APPDOMAINREF pDomain; } gc; ZeroMemory(&gc, sizeof(gc)); GCPROTECT_BEGIN(gc); gc.pName = COMString::NewString(pwzFriendlyName); if(pSetup) gc.pSetup = GetObjectRefFromComIP(pSetup); if(pEvidence) gc.pEvidence = GetObjectRefFromComIP(pEvidence); MethodDesc *pMD = g_Mscorlib.GetMethod(METHOD__APP_DOMAIN__CREATE_DOMAIN); ARG_SLOT args[3] = { ObjToArgSlot(gc.pName), ObjToArgSlot(gc.pEvidence), ObjToArgSlot(gc.pSetup), }; gc.pDomain = (APPDOMAINREF) ArgSlotToObj(pMD->Call(args, METHOD__APP_DOMAIN__CREATE_DOMAIN)); IfFailThrow(QuickCOMStartup()); *pAppDomain = GetComIPFromObjectRef((OBJECTREF*) &gc.pDomain); GCPROTECT_END(); } COMPLUS_CATCH { hr = SecurityHelper::MapToHR(GETTHROWABLE()); } COMPLUS_END_CATCH if (fWasGCEnabled) pThread->EnablePreemptiveGC(); Exit: ENDCANNOTTHROWCOMPLUSEXCEPTION(); return hr; }
HRESULT STDMETHODCALLTYPE ICorDBPrivHelperImpl::GetManagedObjectContents( /* in */ IUnknown *pObject, /* in */ void *rawData, /* in */ ULONG32 dataSize) { if (!pObject || !rawData) return E_POINTER; if (dataSize == 0) return E_INVALIDARG; HRESULT hr = S_OK; BEGINCANNOTTHROWCOMPLUSEXCEPTION(); // This will set up a managed thread object if one does not already exist // for this particular thread. Thread* pThread = SetupThread(); if (pThread == NULL) { hr = E_OUTOFMEMORY; goto Exit; } { // Don't want to be interrupted... BOOL fWasGCEnabled = !pThread->PreemptiveGCDisabled(); if (fWasGCEnabled) pThread->DisablePreemptiveGC(); OBJECTREF obj = NULL; GCPROTECT_BEGIN(obj); COMPLUS_TRY { // Get the Object out of the IUnknown. obj = GetObjectRefFromComIP(pObject); MethodTable *pMT = obj->GetMethodTable(); if (!pMT->GetClass()->IsValueClass() || pMT->ContainsPointers() || (pMT->GetClass()->GetNumInstanceFieldBytes() != dataSize)) hr = CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS; // This is the nasty part. We're gonna copy the raw data out // of the object and pass it out. if (SUCCEEDED(hr)) { memcpy(rawData, obj->UnBox(), dataSize); } } COMPLUS_CATCH { // If there's an exception, convert it to an HR hr = SecurityHelper::MapToHR(GETTHROWABLE()); } COMPLUS_END_CATCH obj = NULL; GCPROTECT_END(); // obj if (fWasGCEnabled) pThread->EnablePreemptiveGC(); } Exit: ENDCANNOTTHROWCOMPLUSEXCEPTION(); return (hr); }