示例#1
0
HRESULT CorHost::UnloadDomain(IUnknown *pUnkDomain)
{
    HRESULT hr = S_OK;
    if(!pUnkDomain) return E_POINTER;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();
    Thread* pThread = GetThread();
    if (!pThread)
        IfFailGo(E_UNEXPECTED);

    IfFailGo(QuickCOMStartup());

    BEGIN_ENSURE_COOPERATIVE_GC();

    COMPLUS_TRY {
		// unload doesn't need to switch to the domain to be unloaded
		OBJECTREF pRef = NULL;
		GCPROTECT_BEGIN(pRef);
		pRef = GetObjectRefFromComIP(pUnkDomain);
		MethodDesc* pMD = g_Mscorlib.GetMethod(METHOD__APP_DOMAIN__UNLOAD);
		ARG_SLOT arg = ObjToArgSlot((OBJECTREF) pRef);
		pMD->Call(&arg, METHOD__APP_DOMAIN__UNLOAD);
		GCPROTECT_END();
    } COMPLUS_CATCH {
        hr = SecurityHelper::MapToHR(GETTHROWABLE());
    } COMPLUS_END_CATCH
          
    END_ENSURE_COOPERATIVE_GC();

ErrExit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return hr;
}
示例#2
0
文件: binder.cpp 项目: ArildF/masters
TypeHandle Binder::LookupType(BinderTypeID id, BOOL fLoad)
{
    _ASSERTE(m_pModule != NULL);
    _ASSERTE(id != TYPE__NIL);
    _ASSERTE(id <= m_cTypeHandles);

    THROWSCOMPLUSEXCEPTION();

    TypeHandle th;

    const TypeDescription *d = m_typeDescriptions + id - 1;

    OBJECTREF pThrowable = NULL;
    GCPROTECT_BEGIN(pThrowable);

    NameHandle nh(d->type, TypeHandle(GetClass(d->classID)), d->rank);
    if (!fLoad)
        nh.SetTokenNotToLoad(tdAllTypes);
    th = m_pModule->GetClassLoader()->FindTypeHandle(&nh, &pThrowable);

    GCPROTECT_END();

    if (th.IsNull())
    {
        if (fLoad)
            COMPlusThrow(pThrowable);
        return TypeHandle();
    }

    m_pTypeHandles[id-1] = th;

    return th;
}
示例#3
0
文件: binder.cpp 项目: ArildF/masters
void Binder::InitClass(MethodTable *pMT)
{
    THROWSCOMPLUSEXCEPTION();

    OBJECTREF throwable = NULL;
    GCPROTECT_BEGIN(throwable);

    if (!pMT->CheckRunClassInit(&throwable))
        COMPlusThrow(throwable);

    GCPROTECT_END();
}
示例#4
0
文件: binder.cpp 项目: ArildF/masters
MethodTable *Binder::LookupClass(BinderClassID id, BOOL fLoad)
{
    _ASSERTE(m_pModule != NULL);
    _ASSERTE(id != CLASS__NIL);
    _ASSERTE(id <= m_cClassRIDs);

    MethodTable *pMT;

    const ClassDescription *d = m_classDescriptions + id - 1;

    NameHandle nh(d->name);

    if (!fLoad)
    {
        nh.SetTokenNotToLoad(tdAllTypes);
        pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh).AsMethodTable();
        if (pMT == NULL)
            return NULL;
    }
    else
    {
        THROWSCOMPLUSEXCEPTION();

        BEGIN_ENSURE_COOPERATIVE_GC();
        OBJECTREF pThrowable = NULL;
        GCPROTECT_BEGIN(pThrowable);

        pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh, &pThrowable).AsMethodTable();
        if (pMT == NULL)
        {
            _ASSERTE(!"EE expects class to exist");
            COMPlusThrow(pThrowable);
        }
        GCPROTECT_END();
        END_ENSURE_COOPERATIVE_GC();
    }

    _ASSERTE(pMT->GetModule() == m_pModule);

    mdTypeDef td = pMT->GetClass()->GetCl();

    _ASSERTE(!IsNilToken(td));

    _ASSERTE(RidFromToken(td) <= USHRT_MAX);
    m_pClassRIDs[id-1] = (USHORT) RidFromToken(td);

    m_pModule->StoreTypeDef(td, pMT);

    return pMT;
}
示例#5
0
static IUnknown* GetDomainsExposedObjectWorker(Thread* pThread, AppDomain* pDomain)
{
    HRESULT hr = S_OK;
    IUnknown* punk = NULL;
    OBJECTREF ref = NULL;
    GCPROTECT_BEGIN(ref);
    DECLARE_ALLOCA_CONTEXT_TRANSITION_FRAME(pFrame);
    // ok to do this here as we are just grabbing a wrapper. No managed code will run
    pThread->EnterContextRestricted(pDomain->GetDefaultContext(), pFrame, TRUE);
    ref = pDomain->GetExposedObject();
    IfFailThrow(QuickCOMStartup());   
    punk = GetComIPFromObjectRef(&ref);
    pThread->ReturnToContext(pFrame, TRUE);
    GCPROTECT_END();
    return punk;
}
示例#6
0
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;
}
示例#7
0
HRESULT AssemblySpec::CheckFileAccess(LPCWSTR wszFile,DWORD dwAccess)
{
    BOOL bRes=FALSE;

    BEGIN_ENSURE_COOPERATIVE_GC();
    STRINGREF sFileName=NULL;

    GCPROTECT_BEGIN(sFileName);
    sFileName = COMString::NewString(wszFile);
    ARG_SLOT args[]={
    ObjToArgSlot(sFileName),
    dwAccess,
    };
    
    bRes = Security::CheckFileAccess(args);
    GCPROTECT_END();
    END_ENSURE_COOPERATIVE_GC();
    return bRes ? S_OK : HRESULT_FROM_WIN32(E_ACCESSDENIED);
    
};
示例#8
0
HRESULT CorHost::CreateDomainSetup(IUnknown **pAppDomainSetup)
{
    HRESULT hr = S_OK;

    if (!pAppDomainSetup)
        return E_POINTER;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();
    // Create the domain. 
    Thread* pThread = GetThread();
    if (!pThread)
        IfFailGo(E_UNEXPECTED);

    IfFailGo(QuickCOMStartup());

    BEGIN_ENSURE_COOPERATIVE_GC();

    COMPLUS_TRY {
        struct _gc {
            OBJECTREF pSetup;
        } gc;
        ZeroMemory(&gc, sizeof(gc));

        MethodTable* pMT = g_Mscorlib.GetClass(CLASS__APPDOMAIN_SETUP);
        GCPROTECT_BEGIN(gc);
        gc.pSetup = AllocateObject(pMT);
        IfFailThrow(QuickCOMStartup());   
        *pAppDomainSetup = GetComIPFromObjectRef((OBJECTREF*) &gc.pSetup);
        GCPROTECT_END();
    } COMPLUS_CATCH {
        hr = SecurityHelper::MapToHR(GETTHROWABLE());
    } COMPLUS_END_CATCH
          
    END_ENSURE_COOPERATIVE_GC();

 ErrExit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return hr;
}
示例#9
0
Object * FinalizerThread::DoOneFinalization(Object* fobj, Thread* pThread,int bitToCheck,bool *pbTerminate)
{
    STATIC_CONTRACT_THROWS;
    STATIC_CONTRACT_GC_TRIGGERS;
    STATIC_CONTRACT_MODE_COOPERATIVE;

    bool fTerminate=false;
    Object *pReturnObject = NULL;
    

    AppDomain* targetAppDomain = fobj->GetAppDomain();
    AppDomain* currentDomain = pThread->GetDomain();
    if (! targetAppDomain || ! targetAppDomain->CanThreadEnter(pThread))
    {
        // if can't get into domain to finalize it, then it must be agile so finalize in current domain
        targetAppDomain = currentDomain;
#if CHECK_APP_DOMAIN_LEAKS
        {
        // object must be agile if can't get into it's domain
        if (g_pConfig->AppDomainLeaks() && !fobj->TrySetAppDomainAgile(FALSE))   
            _ASSERTE(!"Found non-agile GC object which should have been finalized during app domain unload.");
        }
#endif
    }

    if (targetAppDomain == currentDomain)
    {
        if (!targetAppDomain->IsRudeUnload() ||
            fobj->GetMethodTable()->HasCriticalFinalizer())
        {
            class ResetFinalizerStartTime
            {
            public:
                ResetFinalizerStartTime()
                {
                    if (CLRHosted())
                    {
                        g_ObjFinalizeStartTime = CLRGetTickCount64();
                    }                    
                }
                ~ResetFinalizerStartTime()
                {
                    if (g_ObjFinalizeStartTime)
                    {
                        g_ObjFinalizeStartTime = 0;
                    }
                }
            };
            {
                ThreadLocaleHolder localeHolder;

                {
                    ResetFinalizerStartTime resetTime;
                    CallFinalizer(fobj);
                }
            }
            pThread->InternalReset(FALSE);
        }
    } 
    else 
    {
        if (! targetAppDomain->GetDefaultContext())
        {
            // Can no longer enter domain becuase the handle containing the context has been
            // destroyed so just bail. Should only get this if are at the stage of nuking the
            // handles in the domain if it's still open.
            _ASSERTE(targetAppDomain->IsUnloading() && targetAppDomain->ShouldHaveFinalization());
        }
        else if (!currentDomain->IsDefaultDomain())
        {
            // this means we are in some other domain, so need to return back out through the DoADCallback
            // and handle the object from there in another domain.
            pReturnObject = fobj;
            fTerminate = true;
        } 
        else
        {
            // otherwise call back to ourselves to process as many as we can in that other domain
            FinalizeAllObjects_Args args;
            args.fobj = ObjectToOBJECTREF(fobj);
            args.bitToCheck = bitToCheck;
            GCPROTECT_BEGIN(args.fobj);
            {
                ThreadLocaleHolder localeHolder;

                _ASSERTE(pThreadTurnAround != NULL);
                ManagedThreadBase::FinalizerAppDomain(targetAppDomain,
                                                      FinalizeAllObjects_Wrapper,
                                                      &args,
                                                      pThreadTurnAround);
            }
            pThread->InternalReset(FALSE);
            // process the object we got back or be done if we got back null
            pReturnObject = OBJECTREFToObject(args.fobj);
            GCPROTECT_END();
        }
    }        
        
    *pbTerminate = fTerminate;
    return pReturnObject;
}
示例#10
0
CustomMarshalerInfo::CustomMarshalerInfo(BaseDomain *pDomain, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes)
: m_NativeSize(0)
, m_hndManagedType(hndManagedType)
, m_hndCustomMarshaler(NULL)
, m_pMarshalNativeToManagedMD(NULL)
, m_pMarshalManagedToNativeMD(NULL)
, m_pCleanUpNativeDataMD(NULL)
, m_pCleanUpManagedDataMD(NULL)
, m_bDataIsByValue(FALSE)
{
    CONTRACTL
    {
        THROWS;
        GC_TRIGGERS;
        MODE_COOPERATIVE;
        PRECONDITION(CheckPointer(pDomain));
    }
    CONTRACTL_END;


    // Make sure the custom marshaller implements ICustomMarshaler.
    if (!hndCustomMarshalerType.GetMethodTable()->CanCastToNonVariantInterface(MscorlibBinder::GetClass(CLASS__ICUSTOM_MARSHALER)))
    {
        DefineFullyQualifiedNameForClassW()
        COMPlusThrow(kApplicationException,
                     IDS_EE_ICUSTOMMARSHALERNOTIMPL,
                     GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable()));
    }

    // Determine if this type is a value class.
    m_bDataIsByValue = m_hndManagedType.GetMethodTable()->IsValueType();

    // Custom marshalling of value classes is not currently supported.
    if (m_bDataIsByValue)
        COMPlusThrow(kNotSupportedException, W("NotSupported_ValueClassCM"));

#ifndef CROSSGEN_COMPILE
    // Run the <clinit> on the marshaler since it might not have run yet.
    hndCustomMarshalerType.GetMethodTable()->EnsureInstanceActive();
    hndCustomMarshalerType.GetMethodTable()->CheckRunClassInitThrowing();

    // Create a COM+ string that will contain the string cookie.
    STRINGREF CookieStringObj = StringObject::NewString(strCookie, cCookieStrBytes);
    GCPROTECT_BEGIN(CookieStringObj);
#endif

    // Load the method desc's for all the methods in the ICustomMarshaler interface.
    m_pMarshalNativeToManagedMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalNativeToManaged, hndCustomMarshalerType);
    m_pMarshalManagedToNativeMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalManagedToNative, hndCustomMarshalerType);
    m_pCleanUpNativeDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpNativeData, hndCustomMarshalerType);
    m_pCleanUpManagedDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpManagedData, hndCustomMarshalerType);

    // Load the method desc for the static method to retrieve the instance.
    MethodDesc *pGetCustomMarshalerMD = GetCustomMarshalerMD(CustomMarshalerMethods_GetInstance, hndCustomMarshalerType);

    // If the GetInstance method is generic, get an instantiating stub for it -
    // the CallDescr infrastructure doesn't know how to pass secret generic arguments.
    if (pGetCustomMarshalerMD->RequiresInstMethodTableArg())
    {
        pGetCustomMarshalerMD = MethodDesc::FindOrCreateAssociatedMethodDesc(
            pGetCustomMarshalerMD,
            hndCustomMarshalerType.GetMethodTable(), 
            FALSE,           // forceBoxedEntryPoint
            Instantiation(), // methodInst
            FALSE,           // allowInstParam
            FALSE);          // forceRemotableMethod

        _ASSERTE(!pGetCustomMarshalerMD->RequiresInstMethodTableArg());
    }

#ifndef CROSSGEN_COMPILE
    MethodDescCallSite getCustomMarshaler(pGetCustomMarshalerMD, (OBJECTREF*)&CookieStringObj);

    pGetCustomMarshalerMD->EnsureActive();

    // Prepare the arguments that will be passed to GetCustomMarshaler.
    ARG_SLOT GetCustomMarshalerArgs[] = { 
        ObjToArgSlot(CookieStringObj)
    };

    // Call the GetCustomMarshaler method to retrieve the custom marshaler to use.
    OBJECTREF CustomMarshalerObj = getCustomMarshaler.Call_RetOBJECTREF(GetCustomMarshalerArgs);
    if (!CustomMarshalerObj)
    {
        DefineFullyQualifiedNameForClassW()
        COMPlusThrow(kApplicationException,
                     IDS_EE_NOCUSTOMMARSHALER,
                     GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable()));
    }
    m_hndCustomMarshaler = pDomain->CreateHandle(CustomMarshalerObj);

    // Retrieve the size of the native data.
    if (m_bDataIsByValue)
    {
        // <TODO>@TODO(DM): Call GetNativeDataSize() to retrieve the size of the native data.</TODO>
        _ASSERTE(!"Value classes are not yet supported by the custom marshaler!");
    }
    else
    {
        m_NativeSize = sizeof(void *);
    }

    GCPROTECT_END();
#endif
}
示例#11
0
VOID ComCallWrapper::InvokeByNameCallback(LPVOID ptr)
{
    InvokeByNameArgs* args = (InvokeByNameArgs*)ptr;
    INT32 NumByrefArgs = 0;
    INT32 *aByrefArgMngVariantIndex = NULL;
    INT32 iArg;
    struct __gc {
        OBJECTREF Target;
        STRINGREF MemberName;
        PTRARRAYREF ParamArray;
        OBJECTREF TmpObj;
        OBJECTREF RetVal;
    } gc;
    ZeroMemory(&gc, sizeof(gc));

    GCPROTECT_BEGIN(gc);

    gc.MemberName = COMString::NewString(args->MemberName);

    gc.ParamArray = (PTRARRAYREF)AllocateObjectArray(args->ArgCount, g_pObjectClass);

    //
    // Fill in the arguments.
    //

    for (iArg = 0; iArg < args->ArgCount; iArg++)
    {
        // Convert the variant.
        VARIANT *pSrcOleVariant = &args->ArgList[iArg];
        OleVariant::MarshalObjectForOleVariant(pSrcOleVariant, &gc.TmpObj);
        gc.ParamArray->SetAt(iArg, gc.TmpObj);

        // If the argument is byref then add it to the array of byref arguments.
        if (V_VT(pSrcOleVariant) & VT_BYREF)
        {
            if (aByrefArgMngVariantIndex == NULL) {
                aByrefArgMngVariantIndex = (INT32 *)_alloca(sizeof(INT32) * args->ArgCount);
            }

            aByrefArgMngVariantIndex[NumByrefArgs] = iArg;
            NumByrefArgs++;
        }
    }

    gc.Target = ObjectFromHandle(args->pThis->m_hThis);

    //
    // Invoke using IReflect::InvokeMember
    //

    EEClass *pClass = gc.Target->GetClass();

    // Retrieve the method descriptor that will be called on.
    MethodDesc *pMD = GetInvokeMemberMD();

    // Prepare the arguments that will be passed to Invoke.
    ARG_SLOT Args[] = {
            ObjToArgSlot(GetReflectionObject(pClass)), // IReflect
            ObjToArgSlot(gc.MemberName),    // name
            (ARG_SLOT) args->BindingFlags,  // invokeAttr
            ObjToArgSlot(GetOleAutBinder()),// binder
            ObjToArgSlot(gc.Target),        // target
            ObjToArgSlot(gc.ParamArray),    // args
            ObjToArgSlot(NULL),             // modifiers
            ObjToArgSlot(NULL),             // culture
            ObjToArgSlot(NULL)              // namedParameters
    };

    // Do the actual method invocation.
    MetaSig metaSig(pMD->GetSig(),pMD->GetModule());
    gc.RetVal = ArgSlotToObj(pMD->Call(Args, &metaSig));

    //
    // Convert the return value and the byref arguments.
    //

    // Convert all the ByRef arguments back.
    for (iArg = 0; iArg < NumByrefArgs; iArg++)
    {
        INT32 i = aByrefArgMngVariantIndex[iArg];
        gc.TmpObj = gc.ParamArray->GetAt(i);
        OleVariant::MarshalOleRefVariantForObject(&gc.TmpObj, &args->ArgList[i]);
    }

    // Convert the return COM+ object to an OLE variant.
    if (args->pRetVal)
        OleVariant::MarshalOleVariantForObject(&gc.RetVal, args->pRetVal);

    GCPROTECT_END();
}
示例#12
0
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);
}
示例#13
0
// 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;
}
示例#14
0
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);
}
示例#15
0
//+----------------------------------------------------------------------------
//
//  Method:     CStackBuilderSink::PrivateProcessMessage, public
//
//  Synopsis:   Builds the stack and calls an object
//
//+----------------------------------------------------------------------------
FCIMPL7(Object*, CStackBuilderSink::PrivateProcessMessage, Object* pSBSinkUNSAFE, ReflectBaseObject* pMethodBaseUNSAFE, PTRArray* pArgsUNSAFE, Object* pServerUNSAFE, void* iMethodPtr, BOOL fContext, PTRARRAYREF* ppVarOutParams)
{
    OBJECTREF ret = NULL;
    struct _gc
    {
        REFLECTBASEREF pMethodBase;
        PTRARRAYREF pArgs;
        OBJECTREF pServer;
        OBJECTREF pSBSink;
    } gc;
    gc.pMethodBase = (REFLECTBASEREF) pMethodBaseUNSAFE;
    gc.pArgs = (PTRARRAYREF) pArgsUNSAFE;
    gc.pServer = (OBJECTREF) pServerUNSAFE;
    gc.pSBSink = (OBJECTREF) pSBSinkUNSAFE;
    HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_NOPOLL(Frame::FRAME_ATTR_RETURNOBJ);
    GCPROTECT_BEGIN(gc);
    HELPER_METHOD_POLL();
    //-[autocvtpro]-------------------------------------------------------

    THROWSCOMPLUSEXCEPTION();

    TRIGGERSGC();

    LOG((LF_REMOTING, LL_INFO10,
         "CStackBuilderSink::PrivateProcessMessage\n"));
    
    _ASSERTE(gc.pMethodBase != NULL);
    ReflectMethod *pRM = (ReflectMethod *)gc.pMethodBase->GetData();
    MethodDesc *pMD = pRM->pMethod;    

	// Either pServer is non-null or the method is static (but not both)
    _ASSERTE((gc.pServer!=NULL) == !(pMD->IsStatic()));

    // Check if this is an interface invoke, if yes, then we have to find the
    // real method descriptor on the class of the server object.
    if(pMD->GetMethodTable()->IsInterface())
    {
        _ASSERTE(gc.pServer != NULL);

        MethodDesc* pTemp = pMD;
        // NOTE: This method can trigger GC
        pMD = gc.pServer->GetMethodTable()->GetMethodDescForInterfaceMethod(pMD, gc.pServer);
        if(NULL == pMD)
        {
            MAKE_WIDEPTR_FROMUTF8(wName, pTemp->GetName())
            COMPlusThrow(kMissingMethodException, IDS_EE_MISSING_METHOD, NULL, wName);
        }
    }

    MetaSig mSig(pMD->GetSig(), pMD->GetModule());
    
    // get the target depending on whether the method is virtual or non-virtual
    // like a constructor, private or final method
    const BYTE* pTarget = NULL;
     
    if (iMethodPtr) 
    {
        pTarget = (const BYTE*) iMethodPtr;
    }
    else
    {
        // Get the address of the code
        pTarget = MethodTable::GetTargetFromMethodDescAndServer(pMD, &(gc.pServer), fContext);    
    }
    

    VASigCookie *pCookie = NULL;
    _ASSERTE(NULL != pTarget);
    GCPROTECT_BEGIN (ret);
            // this function does the work
    ::CallDescrWithObjectArray(
            gc.pServer, 
            pRM, 
            pTarget, 
            &mSig, 
            pCookie, 
            gc.pServer==NULL?TRUE:FALSE, //fIsStatic
            gc.pArgs, 
            &ret,
            ppVarOutParams);
    GCPROTECT_END ();

    LOG((LF_REMOTING, LL_INFO10,
         "CStackBuilderSink::PrivateProcessMessage OUT\n"));

        //-[autocvtepi]-------------------------------------------------------
    GCPROTECT_END();
    HELPER_METHOD_FRAME_END();
    return OBJECTREFToObject(ret);
}