// static 
ThreadStore * ThreadStore::Create(RuntimeInstance * pRuntimeInstance)
{
    NewHolder<ThreadStore> pNewThreadStore = new (nothrow) ThreadStore();
    if (NULL == pNewThreadStore)
        return NULL;

    pNewThreadStore->m_SuspendCompleteEvent.CreateManualEvent(TRUE);

    pNewThreadStore->m_pRuntimeInstance = pRuntimeInstance;

    pNewThreadStore.SuppressRelease();
    return pNewThreadStore;
}
Esempio n. 2
0
// Create a new thread
// Parameters:
//  function - the function to be executed by the thread
//  param    - parameters of the thread
//  affinity - processor affinity of the thread
// Return:
//  true if it has succeeded, false if it has failed
bool GCToOSInterface::CreateThread(GCThreadFunction function, void* param, GCThreadAffinity* affinity)
{
    LIMITED_METHOD_CONTRACT;

    uint32_t thread_id;

    NewHolder<GCThreadStubParam> stubParam = new (nothrow) GCThreadStubParam();
    if (stubParam == NULL)
    {
        return false;
    }

    stubParam->GCThreadFunction = function;
    stubParam->GCThreadParam = param;

    HANDLE gc_thread = Thread::CreateUtilityThread(Thread::StackSize_Medium, GCThreadStub, stubParam, CREATE_SUSPENDED, (DWORD*)&thread_id);

    if (!gc_thread)
    {
        return false;
    }

    stubParam.SuppressRelease();

    SetThreadPriority(gc_thread, /* THREAD_PRIORITY_ABOVE_NORMAL );*/ THREAD_PRIORITY_HIGHEST );

#ifndef FEATURE_PAL
    if (affinity->Group != GCThreadAffinity::None)
    {
        _ASSERTE(affinity->Processor != GCThreadAffinity::None);
        GROUP_AFFINITY ga;
        ga.Group = (WORD)affinity->Group;
        ga.Reserved[0] = 0; // reserve must be filled with zero
        ga.Reserved[1] = 0; // otherwise call may fail
        ga.Reserved[2] = 0;
        ga.Mask = (size_t)1 << affinity->Processor;

        CPUGroupInfo::SetThreadGroupAffinity(gc_thread, &ga, NULL);
    }
    else if (affinity->Processor != GCThreadAffinity::None)
    {
        SetThreadAffinityMask(gc_thread, (DWORD_PTR)1 << affinity->Processor);
    }
#endif // !FEATURE_PAL

    ResumeThread(gc_thread);
    CloseHandle(gc_thread);

    return true;
}
Esempio n. 3
0
    HRESULT PropertyMap::Add(SString *pPropertyName,
                             SBuffer *pPropertyValue)
    {
        _ASSERTE(pPropertyName != NULL);
        _ASSERTE(pPropertyValue != NULL);

        HRESULT hr = S_OK;

        NewHolder<PropertyEntry> pPropertyEntry;
        SAFE_NEW(pPropertyEntry, PropertyEntry);

        pPropertyEntry->SetPropertyName(pPropertyName);
        pPropertyEntry->SetPropertyValue(pPropertyValue);
        
        SHash<PropertyHashTraits>::Add(pPropertyEntry);
        pPropertyEntry.SuppressRelease();
        
    Exit:
        return hr;
    }
Esempio n. 4
0
HRESULT CCoreCLRBinderHelper::GetAssemblyIdentity(LPCSTR     szTextualIdentity,
        BINDER_SPACE::ApplicationContext  *pApplicationContext,
        NewHolder<AssemblyIdentityUTF8> &assemblyIdentityHolder)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(szTextualIdentity != NULL);

    EX_TRY
    {
        AssemblyIdentityUTF8 *pAssemblyIdentity = NULL;
        if (pApplicationContext != NULL)
        {
            // This returns a cached copy owned by application context
            hr = pApplicationContext->GetAssemblyIdentity(szTextualIdentity, &pAssemblyIdentity);
            if(SUCCEEDED(hr))
            {
                assemblyIdentityHolder = pAssemblyIdentity;
                assemblyIdentityHolder.SuppressRelease();
            }
        }
        else
        {
            SString sTextualIdentity;

            sTextualIdentity.SetUTF8(szTextualIdentity);

            // This is a private copy
            pAssemblyIdentity = new AssemblyIdentityUTF8();
            hr = TextualIdentityParser::Parse(sTextualIdentity, pAssemblyIdentity);
            if(SUCCEEDED(hr))
            {
                pAssemblyIdentity->PopulateUTF8Fields();
                assemblyIdentityHolder = pAssemblyIdentity;
            }
        }
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}
Esempio n. 5
0
//---------------------------------------------------------------------------------------
// 
// Initialize the static instance and lock.
// 
HRESULT 
LOADEDMODULES::InitializeStatics()
{
    HRESULT hr = S_OK;
    
    if (VolatileLoad(&s_pLoadedModules) == NULL)
    {
        // Initialize global read-write lock
        {
            NewHolder<UTSemReadWrite> pSemReadWrite = new (nothrow) UTSemReadWrite();
            IfNullGo(pSemReadWrite);
            IfFailGo(pSemReadWrite->Init());
            
            if (InterlockedCompareExchangeT<UTSemReadWrite *>(&m_pSemReadWrite, pSemReadWrite, NULL) == NULL)
            {   // We won the initialization race
                pSemReadWrite.SuppressRelease();
            }
        }
        
        // Initialize the global instance
        {
            NewHolder<LOADEDMODULES> pLoadedModules = new (nothrow) LOADEDMODULES();
            IfNullGo(pLoadedModules);
            
            {
                LOCKWRITE();
                
                if (VolatileLoad(&s_pLoadedModules) == NULL)
                {
                    VolatileStore(&s_pLoadedModules, pLoadedModules.Extract());
                }
            }
        }
    }
    
ErrExit:
    return hr;
} // LOADEDMODULES::InitializeStatics
Esempio n. 6
0
//=====================================================================================================================
HRESULT CLRPrivBinderAppX::BindAppXAssemblyByNameWorker(
    IAssemblyName * pIAssemblyName,
    DWORD dwAppXBindFlags,
    CLRPrivAssemblyAppX ** ppAssembly)
{
    STANDARD_VM_CONTRACT;
    HRESULT hr = S_OK;

    fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_IMMERSIVE, &hr);

    VALIDATE_ARG_RET(pIAssemblyName != nullptr);
    VALIDATE_ARG_RET((dwAppXBindFlags & ABF_BindIL) == ABF_BindIL);
    VALIDATE_ARG_RET(ppAssembly != nullptr);

    DWORD dwContentType = AssemblyContentType_Default;
    IfFailRet(hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CONTENT_TYPE, &dwContentType));
    if ((hr == S_OK) && (dwContentType != AssemblyContentType_Default))
    {
        IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
    }

    ReleaseHolder<CLRPrivAssemblyAppX> pAssembly;

    // Get the simple name.
    WCHAR wzSimpleName[_MAX_PATH];
    DWORD cchSimpleName = _MAX_PATH;
    IfFailRet(pIAssemblyName->GetName(&cchSimpleName, wzSimpleName));

    {   // Look for previous successful bind. Host callouts are now forbidden.
        ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
        pAssembly = clr::SafeAddRef(m_NameToAssemblyMap.Lookup(wzSimpleName));
    }

    if (pAssembly == nullptr)
    {
        ReleaseHolder<ICLRPrivResource> pResourceIL;
        ReleaseHolder<ICLRPrivResource> pResourceNI;

        // Create assembly identity using the simple name. For successful binds this will be updated
        // with the full assembly identity in the VerifyBind callback.
        NewHolder<AssemblyIdentity> pIdentity = new AssemblyIdentity();
        IfFailRet(pIdentity->Initialize(wzSimpleName));

        //
        // Check the head package first to see if this matches an EXE, then check
        // all packages to see if this matches a DLL.
        //
        WCHAR wzFilePath[_MAX_PATH];
        {
            hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

            if (FAILED(hr))
            {
                // Create simple name with .EXE extension
                WCHAR wzSimpleFileName[_MAX_PATH];
                wcscpy_s(wzSimpleFileName, NumItems(wzSimpleFileName), wzSimpleName);
                wcscat_s(wzSimpleFileName, NumItems(wzSimpleFileName), W(".EXE"));

                // Search for the file using AppX::FileFileInCurrentPackage helper.
                UINT32 cchFilePath = NumItems(wzFilePath);
                hr = AppX::FindFileInCurrentPackage(
                        wzSimpleFileName,
                        &cchFilePath,
                        wzFilePath,
                        PACKAGE_FILTER_CLR_DEFAULT,
                        (PCWSTR *)(void *)m_rgAltPaths,
                        m_cAltPaths,
                        m_pParentBinder != NULL ? AppX::FindFindInPackageFlags_SkipCurrentPackageGraph : AppX::FindFindInPackageFlags_None);
            }

            if (FAILED(hr))
            {
                // Create simple name with .DLL extension
                WCHAR wzSimpleFileName[_MAX_PATH];
                wcscpy_s(wzSimpleFileName, NumItems(wzSimpleFileName), wzSimpleName);
                wcscat_s(wzSimpleFileName, NumItems(wzSimpleFileName), W(".DLL"));

                // Search for the file using AppX::FileFileInCurrentPackage helper
                UINT32 cchFilePath = NumItems(wzFilePath);
                hr = AppX::FindFileInCurrentPackage(
                        wzSimpleFileName,
                        &cchFilePath,
                        wzFilePath,
                        PACKAGE_FILTER_CLR_DEFAULT,
                        (PCWSTR *)(void *)m_rgAltPaths,
                        m_cAltPaths,
                        m_pParentBinder != NULL ? AppX::FindFindInPackageFlags_SkipCurrentPackageGraph : AppX::FindFindInPackageFlags_None);
            }

            if (SUCCEEDED(hr))
            {
                fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FOUND, wzFilePath);
            }
            else
            {
                // Cache the bind failure result before returning. Careful not to overwrite the bind result with the cache insertion result.
                HRESULT hrResult = hr;
                IfFailRet(CacheBindResult(pIdentity, hr));
                if (hr == S_OK)
                {   // Cache now owns identity object lifetime.
                    pIdentity.SuppressRelease();
                }
                hr = hrResult;
            }
            IfFailRet(hr);
        }

        NewHolder<CLRPrivResourcePathImpl> pResourcePath = new CLRPrivResourcePathImpl(wzFilePath);
        IfFailRet(pResourcePath->QueryInterface(__uuidof(ICLRPrivResource), (LPVOID*)&pResourceIL));
        pResourcePath.SuppressRelease();

        // Create an IBindResult and provide it to the new CLRPrivAssemblyAppX object.
        ReleaseHolder<IBindResult> pIBindResult = ToInterface<IBindResult>(
            new CLRPrivAssemblyBindResultWrapper(pIAssemblyName, wzFilePath, m_pFingerprintFactory));


        // Create the new CLRPrivAssemblyAppX object.
        NewHolder<CLRPrivAssemblyAppX> pAssemblyObj =
            new CLRPrivAssemblyAppX(pIdentity, this, pResourceIL, pIBindResult);

        //
        // Check cache. If someone beat us then use it instead; otherwise add new ICLRPrivAssembly.
        //
        do
        {
            // Because the read lock must be taken within a ForbidSuspend region, use AddInPhases.
            if (m_NameToAssemblyMap.CheckAddInPhases<ForbidSuspendThreadCrstHolder, CrstHolder>(
                    pAssemblyObj, m_MapReadLock, m_MapWriteLock, pAssemblyObj.GetValue()))
            {
                {   // Careful not to allow the cache insertion result to overwrite the bind result.
                    HRESULT hrResult = hr;
                    IfFailRet(CacheBindResult(pIdentity, hr));
                    if (hr == S_OK)
                    {   // Cache now owns identity object lifetime, but ~CLRPrivBinderAssembly
                        // can also remove the identity from the cache prior to cache deletion.
                        pIdentity.SuppressRelease();
                    }
                    hr = hrResult;
                }
                
                pAssembly = pAssemblyObj.Extract();
            }
            else
            {
                ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
                pAssembly = clr::SafeAddRef(m_NameToAssemblyMap.Lookup(wzSimpleName));
            }
        }
        while (pAssembly == nullptr); // Keep looping until we find the existing one, or add a new one
    }

    _ASSERTE(pAssembly != nullptr);

    if (((dwAppXBindFlags & ABF_BindNI) == ABF_BindNI) && 
        m_fCanUseNativeImages)
    {
        //
        // Look to see if there's a native image available.
        //

        // Fire BindingNgenPhaseStart ETW event if enabled.
        {
            InlineSString<128> ssAssemblyName;
            FireEtwBindingNgenPhaseStart(
                (AppDomain::GetCurrentDomain()->GetId().m_dwId),
                LOADCTX_TYPE_HOSTED,
                ETWFieldUnused,
                ETWLoaderLoadTypeNotAvailable,
                NULL,
                FusionBind::GetAssemblyNameDisplayName(pIAssemblyName, ssAssemblyName, ASM_DISPLAYF_FULL).GetUnicode(),
                GetClrInstanceId());
        }

        ReleaseHolder<IBindResult> pIBindResultIL;
        IfFailRet(pAssembly->GetIBindResult(&pIBindResultIL));
        _ASSERTE(pIBindResultIL != nullptr);

        NewArrayHolder<WCHAR> wzZapSet = DuplicateStringThrowing(g_pConfig->ZapSet());
        NativeConfigData cfgData = {
            wzZapSet,
            PEFile::GetNativeImageConfigFlags()
        };

        IfFailRet(BindToNativeAssembly(
            pIBindResultIL, &cfgData, static_cast<IBindContext*>(this), fusion::logging::GetCurrentFusionBindLog()));

        // Ensure that the native image found above in BindToNativeAssembly is reported as existing in the CLRPrivAssembly object
        if (hr == S_OK)
        {
            ReleaseHolder<ICLRPrivResource> pNIImageResource;
            // This will make GetAvailableImageTypes return that a native image exists.
            IfFailRet(pAssembly->GetImageResource(ASSEMBLY_IMAGE_TYPE_NATIVE, NULL, &pNIImageResource));
#ifdef _DEBUG
            DWORD dwImageTypes;

            _ASSERTE(SUCCEEDED(pAssembly->GetAvailableImageTypes(&dwImageTypes)));
            _ASSERTE((dwImageTypes & ASSEMBLY_IMAGE_TYPE_NATIVE) == ASSEMBLY_IMAGE_TYPE_NATIVE);
#endif
        }

        // Fire BindingNgenPhaseEnd ETW event if enabled.
        {
            InlineSString<128> ssAssemblyName;
            FireEtwBindingNgenPhaseEnd(
                (AppDomain::GetCurrentDomain()->GetId().m_dwId),
                LOADCTX_TYPE_HOSTED,
                ETWFieldUnused,
                ETWLoaderLoadTypeNotAvailable,
                NULL,
                FusionBind::GetAssemblyNameDisplayName(pIAssemblyName, ssAssemblyName, ASM_DISPLAYF_FULL).GetUnicode(),
                GetClrInstanceId());
        }

        // BindToNativeAssembly can return S_FALSE, but this could be misleading.
        if (hr == S_FALSE)
            hr = S_OK;
    }

    if (SUCCEEDED(hr))
    {
        *ppAssembly = pAssembly.Extract();
    }

    return hr;
}
Esempio n. 7
0
// Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a runtime in
// that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that can be waited
// on for process termination.
HRESULT DbgTransportTarget::GetTransportForProcess(DWORD                   dwPID,
                                                   DbgTransportSession   **ppTransport,
                                                   HANDLE                 *phProcessHandle)
{
    RSLockHolder lock(&m_sLock);
    HRESULT hr = S_OK;

    ProcessEntry *entry = LocateProcessByPID(dwPID);

    if (entry == NULL)
    {

       NewHolder<ProcessEntry> newEntry = new(nothrow) ProcessEntry();
       if (newEntry == NULL)
           return E_OUTOFMEMORY;

       NewHolder<DbgTransportSession> transport = new(nothrow) DbgTransportSession();
       if (transport == NULL)
       {
           return E_OUTOFMEMORY;
       }


       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
       if (hProcess == NULL)
       {
           transport->Shutdown();
           return HRESULT_FROM_GetLastError();
       }

       // Initialize it (this immediately starts the remote connection process).
       hr = transport->Init(dwPID, hProcess);
       if (FAILED(hr))
       {
           transport->Shutdown();
           CloseHandle(hProcess);
           return hr;
       }

       entry = newEntry;
       newEntry.SuppressRelease();   
       entry->m_dwPID = dwPID;
       entry->m_hProcess = hProcess;
       entry->m_transport = transport;
       transport.SuppressRelease();
       entry->m_cProcessRef = 0;

       // Adding new entry to the list.
       entry->m_pNext = m_pProcessList;
       m_pProcessList = entry;
    }

    entry->m_cProcessRef++;
    _ASSERTE(entry->m_cProcessRef > 0);
    _ASSERTE(entry->m_transport != NULL);
    _ASSERTE(entry->m_hProcess > 0);
    
    *ppTransport = entry->m_transport;
    if (!DuplicateHandle(GetCurrentProcess(), 
                         entry->m_hProcess,
                         GetCurrentProcess(), 
                         phProcessHandle,
                         0,      // ignored since we are going to pass DUPLICATE_SAME_ACCESS
                         FALSE, 
                         DUPLICATE_SAME_ACCESS))
    {
        return HRESULT_FROM_GetLastError();
    }

    return hr;
}